/*
 * FuncionesFat.c
 *
 *  Created on: 28/09/2011
 *      Author: JM
 */

#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include "./includes/utilesConexion.h"
#include "../../Commons/src/includes/nipc.h"
#include "../../Commons/src/includes/BibliotecasGenerales.h"
#include "./includes/variablesGlobales.h"
#include "./includes/estructuraFAT.h"
#include "./includes/funcionesFat.h"
#include "./includes/funcionesUtiles.h"
#include "./includes/utils.h"
#include "includes/cacheArchivos.h"
#include "includes/utilesConexion.h"
#include <sys/mman.h>  /* para la funcion map */
#include <unistd.h>  /* para close */
#include <features.h>
#include <sys/types.h>
#include <sys/stat.h>    /* para la funcion fstat y la estructura struct stat */
#include <fcntl.h>       /* para open */

#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>



/*------------------------------------------------------------------------------------------*/



//----------------------------------------------------FUCIONES TABLA FAT--------------------------------------------------------------------------//


int32_t obtenerClusterLibre(fat_BootSector bootSector)
{
	int32_t n;
	int32_t cantidad = (bootSector.sectores_por_FAT *bootSector.bytes_por_sector)/32;

	for (n = 0; n < cantidad; ++n)
	{
		if(tablaFat[n] == 0x00000000) // ¿El cluster está libre?
		{
			tablaFat[n] = 0xfffffff; //Lo marca como ocupado
			persistirTablaFat(n);

			return n; //Devuelve el número de cluster de la tabla
         }
	 }


        return 0; //Devuelve 0 si no hay ningún cluster libre
}



void agregarClusters(int32_t *tablaFat, int32_t cantidad, fat_BootSector bootSector, int32_t primerCluster) //tESTEAR!
{
	  pthread_mutex_lock(&mutexFat);
	int32_t i=primerCluster,ultimoCluster=0,libre;

	if(tablaFat[i]==0xfffffff){
		ultimoCluster=i;
		tablaFat[ultimoCluster]=crearCadenaClusters(tablaFat,cantidad,bootSector);
		persistirTablaFat(ultimoCluster);
		 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
		return;
	}

	if(tablaFat[i]==0 && cantidad==1){
		tablaFat[i]=0xfffffff;
		persistirTablaFat(ultimoCluster);
		 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
		return;
	}

	if(tablaFat[i]==0){
		//Ver que onda este caso , tiro cualquiera cuando se agrega un solo cluster!!!!!
		tablaFat[i]=0x0fffffff;
		ultimoCluster=i;
		tablaFat[ultimoCluster]=crearCadenaClusters(tablaFat,cantidad,bootSector);
		persistirTablaFat(ultimoCluster);
		 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
		return;
	}

	if(i==0){
		libre=obtenerClusterLibre(bootSector);
		tablaFat[libre]=0x0fffffff;
				ultimoCluster=libre;
				tablaFat[ultimoCluster]=crearCadenaClusters(tablaFat,cantidad,bootSector);
				persistirTablaFat(ultimoCluster);
				 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
				return;
	}


	while(tablaFat[i]!=0xfffffff){
		i=tablaFat[i];
	}


	ultimoCluster=i;
	tablaFat[ultimoCluster] = crearCadenaClusters (tablaFat, cantidad, bootSector);
	persistirTablaFat(ultimoCluster);
	 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
	return;}



int32_t crearCadenaClusters(int32_t *tablaFat, int32_t cantidad, fat_BootSector bootSector)//TESTEAR!
{

	int32_t primerCluster = obtenerClusterLibre(bootSector);
	int32_t clusterAux;
	int32_t n;

	clusterAux = primerCluster;

	for(n=1; n<cantidad; ++n)
	{
		tablaFat[clusterAux]= obtenerClusterLibre(bootSector);
		persistirTablaFat(clusterAux);
		clusterAux = tablaFat [clusterAux];
	}


	return primerCluster; //devuelve el número del primer cluster de la cadena
}



int32_t removerClusters(int32_t *tablaFat, int32_t numeroPrimerCluster, int32_t cantidad)
{
	pthread_mutex_lock(&mutexFat);
	int32_t n,a,j,m,posAnt,cantidClusterAsig=0,primerABorrar,sig;


	n = numeroPrimerCluster;
	//Voy hasta el final de ese archivo...

	if(n==0){
		 pthread_mutex_unlock(&mutexFat);
		 return 0;
	}

	if(tablaFat[n]==0){
		 pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
		return 0;
	}

	cantidClusterAsig+=1;

	while (tablaFat[n] != 0xfffffff)
	{	posAnt=n;
		n = tablaFat[n];
		cantidClusterAsig++;
	}


	if(cantidad==1){
		tablaFat[n] = 0x00000000;
		persistirTablaFat(n);
		pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
		return 0;
	}
	primerABorrar=(cantidClusterAsig-cantidad);
	m=numeroPrimerCluster;
	for(j=0;j<primerABorrar;++j){
		posAnt=m;
		m=tablaFat[m];
	}


	for(a=0; a<cantidad; a++)
	{
		sig=tablaFat[m];
		tablaFat[m]=0x00000000;
		persistirTablaFat(m);
		m=sig;
	};
if(cantidad!=cantidClusterAsig){
	tablaFat[posAnt] = 0xfffffff;
	persistirTablaFat(n);
}
pthread_mutex_unlock(&mutexFat); //---------------------------->Habilito el mutex antes de cada return
	return 0;
}

int32_t clustersDeUnArchivo(int32_t *tablaFat,int32_t primerClusterArch){
	int32_t n=0,cant=1;
	n=primerClusterArch;
	if(primerClusterArch==0){
		cant=0;
		return cant;
	}

int32_t cantTotClusters=(bootSector.sectores_por_FAT*bootSector.bytes_por_sector)/32;

	if(n>cantTotClusters){
		return 0;
	}
	while(tablaFat[n]!=0xfffffff){
		n=tablaFat[n];
		cant++;
	}

return cant;}

int32_t cantidadDeClustersLibres(int32_t *tablaFat,fat_BootSector bootSector){
	int32_t cantTotClusters=0;
	int32_t n;
	int32_t clusLibres=0;
	cantTotClusters=(bootSector.sectores_por_FAT*bootSector.bytes_por_sector)/32; //VER ESTO!!
	for(n=0;n<cantTotClusters;n++){
		if(tablaFat[n]==0x00000000){
			clusLibres++;
		}
	}
	return clusLibres;}


int32_t cantidadDeClustersOcupados(int32_t *tablaFat , fat_BootSector bootSector){
	int32_t cantClusOcupados;
	int32_t cantClusLibres;
	int32_t cantTotClusters;
	cantTotClusters=(bootSector.sectores_por_FAT*bootSector.bytes_por_sector)/32;
	cantClusLibres=cantidadDeClustersLibres(tablaFat,bootSector);
	cantClusOcupados=cantTotClusters-cantClusLibres;

	return cantClusOcupados;}
//--------------------------------------------------------FIN FUNCIONES TABLA FAT---------------------------------------------------------------------//


char * obtenerNombreLargo(fat_nombreLargo lfn ){

	char cadenaEnUTF16[26];
	int tamCadenaUTF16=26;

	char cadenaEnUTF8[tamCadenaUTF16/2];
	int tamCadenaUTF8 = 0;

	memcpy(cadenaEnUTF16, lfn.nombreParte1, 10);
	memcpy(cadenaEnUTF16 + 10, lfn.nombreParte2, 12);
	memcpy(cadenaEnUTF16 + 12 + 10, lfn.nombreParte3, 4);

 unicode_utf16_to_utf8_inbuffer(cadenaEnUTF16, tamCadenaUTF16, cadenaEnUTF8,&tamCadenaUTF8);

	return cadenaEnUTF8;}




int32_t obtenerDirDelCluster(int32_t numeroCluster, fat_BootSector bootSector){

	int32_t dir = bootSector.numero_sectores_reservados + (bootSector.numero_tablas_FAT *bootSector.sectores_por_FAT ) + ((numeroCluster -2) * bootSector.sectores_por_cluster);
	return dir;}




fat_BootSector inicializarBootSector(void *sector,  fat_BootSector bootSector) {

	memcpy(&bootSector, sector, sizeof(fat_BootSector));
	return bootSector;}



int32_t inicializarFSISector(char *sector,  fat_informacion_Sector FSISector) {  //Es el sector 1 el que se usa para cargar esto??

 memcpy(&FSISector, sector, sizeof(fat_informacion_Sector));

return 0;}


//
//int32_t * inicializarTablaFAT(fat_BootSector bootSector){
//	int32_t i,n=0;
//	char* clusterLeido;
//	int32_t nroSec;
//	 tablaFat=calloc(1,bootSector.sectores_por_FAT*bootSector.bytes_por_sector);
//	 int32_t nroClusterInicial,nroClusterFinal;
//	 nroClusterInicial=(((bootSector.numero_sectores_reservados*bootSector.bytes_por_sector))/4096);
//	 nroClusterFinal=(bootSector.sectores_por_FAT*bootSector.bytes_por_sector)/4096;
//	 nroSec=bootSector.numero_sectores_reservados;
//	for(i=0;i<nroClusterFinal;i++){
//		clusterLeido=leerCluster(nroSec);
//		memcpy(((char *)tablaFat)+n*4096,clusterLeido,4096);
//		nroSec+=7;
//		n++;
//	}
//
//return tablaFat;}




int32_t * inicializarTablaFAT(fat_BootSector bootSector){
        int32_t i,n=0,canTotClusters;
       char *clusterLeido;
       canTotClusters=(bootSector.sectores_por_FAT*bootSector.bytes_por_sector);
       tablaFat=calloc(1,bootSector.sectores_por_FAT*bootSector.bytes_por_sector);
        for(i=bootSector.numero_sectores_reservados;i<(bootSector.numero_sectores_reservados+bootSector.sectores_por_FAT);i++){
        	clusterLeido=leerCluster(i);
        	memcpy(((char*)tablaFat)+n*4096,clusterLeido,4096);
                n++;
                i+=7;
        }
        printf("TablaFat Cargada en su totalidad\n");
return tablaFat;}




int32_t persistirTablaFat(int32_t offset){
	int32_t numeroCluster=floorl((offset*4)/(bootSector.bytes_por_sector*bootSector.sectores_por_cluster));
	char clusterAGrabar[4096];
	char clusterForRecord[4096];
	//clusterAGrabar=calloc(1,4096);
	memcpy(clusterAGrabar,tablaFat+((numeroCluster*4096)/4),4096);
	int32_t nroSec=numeroCluster*8+bootSector.numero_sectores_reservados;
	memcpy(clusterForRecord,clusterAGrabar,4096); // para que ande el grabar!
	grabarCluster(nroSec,clusterForRecord);
return 0;}


void mostrarLista (ptrLista Lista){
ptrLista ptr;
ptr=Lista;
if (ptr == NULL){
printf("La lista esta vacia.\n\n");
}
else{
printf("La lista es: \n");
while(ptr !=NULL){
printf("%d --> ", ptr->entradaRaiz.primerClusterHi); //por ejemplo , podria mostrar todos los campos o los que necesite..
ptr=ptr->siguiente;
}
printf("NULL\n\n");
}
}

void mostrarListaN (ptrLista Lista){
	ptrLista ptr;
	fat_nombreLargo lfn;
	char nombreLargo[13];


	ptr=Lista;
	if (ptr == NULL){
		printf("La lista esta vacia.\n\n");
	}
	else{
		printf("La lista es: \n");
		while(ptr !=NULL){
			if(ptr->entradaRaiz.atributos==0x0f){
				memcpy(&lfn,&(ptr->entradaRaiz),sizeof(fat_nombreLargo));
				memcpy(&nombreLargo,obtenerNombreLargo(lfn),13);
				printf("%s --> ", nombreLargo);
				ptr=ptr->siguiente;
			}
			else
			{
				printf("%s --> ", ptr->entradaRaiz.nombre); //por ejemplo , podria mostrar todos los campos o los que necesite..
				ptr=ptr->siguiente;}
		}

	}
	printf("NULL\n\n");
}

void agregarEnListaNombres(ptrListaNom_t *lista, char *nombre){

	ptrListaNom_t ptr=NULL;
	ptrListaNom_t nuevo=calloc(1,sizeof(t_ListaNom));
	memcpy(&nuevo->nombre,nombre,strlen(nombre));
	nuevo->siguiente=NULL;
	ptr=(*lista);
	if(ptr==NULL){
		(*lista)=nuevo;
	}
	else{
		while(ptr->siguiente!=NULL){
			ptr = ptr->siguiente;
		}

		ptr->siguiente=nuevo;
	}
}


void eliminarListaNom(ptrListaNom_t *listaNom){
	ptrListaNom_t ptr;
	ptr=(*listaNom);
	while(ptr!=NULL){
		(*listaNom)=(*listaNom)->siguiente;
		free(ptr);
		ptr=(*listaNom);
	}
	(*listaNom)=NULL;
	printf("se elimino todos los datos\n");
}

void mostrarListaNombres (ptrListaNom_t Lista){
	ptrListaNom_t ptr;
	ptr=Lista;
	if (ptr == NULL){
		printf("La lista esta vacia.\n\n");
	}
	else{
		printf("La lista es: \n");
		while(ptr !=NULL){
			printf("%s --> ", ptr->nombre); //por ejemplo , podria mostrar todos los campos o los que necesite..
			ptr=ptr->siguiente;
		}
		printf("NULL\n\n");
	}
}


void agregarEntradaEnLista(ptrLista *lista, fat_entrada entrada){

	ptrLista ptr=NULL;
	ptrLista nuevo=NULL;

	nuevo=malloc(sizeof(ListaRaiz));
	memcpy(&(nuevo->entradaRaiz),&entrada,sizeof(fat_entrada));
	nuevo->siguiente=NULL;
	ptr=(*lista);
	if(ptr==NULL){
		(*lista)=nuevo;
	}

	else{
		while(ptr->siguiente!=NULL){
			ptr = ptr->siguiente;
		}

		ptr->siguiente=nuevo;
	}
}

int32_t agregarAListaRaiz(ptrLista *lista,char *cluster){
	 pthread_mutex_lock(&mutexRaiz);
	int32_t n;
	int32_t i=0;
	fat_entrada entrada;
	fat_nombreLargo lfn;

	for(n=0;n<128;n++){

		memcpy(&lfn,cluster+i,32);
		if((lfn.sequencia==0x00) || (lfn.sequencia==0xe5)){
			i=i+32;
			continue;
		}
		memcpy(&entrada,cluster+i,sizeof(fat_entrada));
		agregarEntradaEnLista(&(*lista),entrada);


		i=i+32;  //Se va corriendo en el buffer por 32 bytes


	}
	 pthread_mutex_unlock(&mutexRaiz);
	return 0;}


int32_t buscaNombreDevuelveClusterEnListaRaiz(ptrLista lista,char * nombre){

	int32_t numeroCluster;
	fat_nombreLargo lfn;
	char nombreLargo[13];
	char nombreCorto[13];
	char bufferLog[100];
	ptrLista ptr;

	ptr=lista;
	while(ptr!=NULL){
		if(ptr->entradaRaiz.atributos==0x0f){
			memcpy(&lfn,&(ptr->entradaRaiz),sizeof(fat_nombreLargo));
			memcpy(nombreLargo,obtenerNombreLargo(lfn),13);
			if(memcmp(nombre,nombreLargo,sizeof(nombre))==0){
				ptr=ptr->siguiente;
				numeroCluster=hiLowCluster(ptr->entradaRaiz);
				return numeroCluster;
			}
		}
		else {
			memcpy(&nombreCorto,obtenerSFNDeEntrada(ptr->entradaRaiz),13);
				if(memcmp(nombre,nombreCorto,strlen(nombre))==0){
				numeroCluster=hiLowCluster(ptr->entradaRaiz);
				return numeroCluster;
			}

		}
		ptr=ptr->siguiente;
	}
	if(flagLog!=0){
		sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",nombre);
		agregarEntradaLog("Error",bufferLog);}

	return -1;}



uint16_t eliminarEntradalistaRaiz(ptrLista *lista,fat_entrada entrada){
	 pthread_mutex_lock(&mutexRaiz);
	ptrLista ptrEntrada,ptrAnterior;
	ptrEntrada=(*lista);
	if(memcmp(&entrada,&ptrEntrada->entradaRaiz,sizeof(fat_entrada))==0){
		(*lista)=(*lista)->siguiente;
		free(ptrEntrada);
		 pthread_mutex_unlock(&mutexRaiz);
		return 0;
	}
	else{
		ptrAnterior=(*lista);
		ptrEntrada=(*lista)->siguiente;
		while((ptrEntrada != NULL) && (memcmp(&entrada,&ptrEntrada->entradaRaiz,sizeof(fat_entrada)) != 0)){
				ptrAnterior=ptrEntrada;
				ptrEntrada=ptrEntrada->siguiente;
		}
		if(ptrEntrada != NULL){
			ptrAnterior->siguiente=ptrEntrada->siguiente;
			free(ptrEntrada);
			 pthread_mutex_unlock(&mutexRaiz);
			return 0;
		}
	}
	 pthread_mutex_unlock(&mutexRaiz);
	return -1;
}


int32_t elementosListaRaiz(ptrLista lista){
	int32_t cantElem=0;
	ptrLista ptr=NULL;
	ptr=lista;
	while(ptr!=NULL){
		if(ptr->entradaRaiz.atributos==0x0f){
			ptr=ptr->siguiente;
		}
		cantElem++;
		ptr=ptr->siguiente;
	}
	return cantElem;
}




int32_t hiLowCluster(fat_entrada entrada){
	int32_t numeroCluster;
	numeroCluster=entrada.primerClusterHi;
	numeroCluster=(numeroCluster << 16) & 0xFFFF0000;
	numeroCluster=numeroCluster | entrada.primerClusterLow;

	return numeroCluster;
}


void llenarLaEntradaconHiLow(fat_entrada *entrada,int32_t numeroCluster){
	(*entrada).primerClusterLow=numeroCluster & 0x0000FFFF;
	(*entrada).primerClusterHi=(numeroCluster >> 16) & 0x0000FFFF0;
	return;
}

int32_t CantidadArchiDirecEnCluster(char * clusterLeido){
	uint16_t i,cantidArchDirec=0;
	fat_nombreLargo lfn;
	for(i=0;i<128;i++){
		memcpy(&lfn,clusterLeido+i*32,32);
		if(0xe5!=lfn.sequencia){
			if(0x00==lfn.sequencia){
				break;
			}
			cantidArchDirec++;
			if(0x0f==lfn.atributos){
				i++;
			}
		}
	}
	return cantidArchDirec;
}



int32_t buscaNombreEnCluster(char * cluster,char * nombre){  // Devuelve el numero de cluster donde empieza la entrada de ese nombre...


	int32_t n,i=0,numeroCluster;
	char nombreLargo[13];
	char nombreCorto[13];
	fat_entrada entrada;
	fat_nombreLargo lfn;


	for(n=0;n<128;n++){  //128 cluster


		memcpy(&entrada,cluster+i,32);

		if(entrada.atributos==0x0f){
			memcpy(&lfn,&entrada,sizeof(fat_nombreLargo));
			memcpy(&nombreLargo,obtenerNombreLargo(lfn),13);
			if(memcmp(nombre,nombreLargo,strlen(nombreLargo))==0){
				//me corro a la proxima entrada y la casteo por q seguro es de entrada fat ya que no hay mas de una entrada de lfn..
				  cluster=cluster+i+32;
				memcpy(&entrada,cluster,32);
				numeroCluster=hiLowCluster(entrada);
				return numeroCluster;

			}

		}
		memcpy(&nombreCorto,obtenerSFNDeEntrada(entrada),13);
			if(memcmp(nombre,nombreCorto,strlen(nombre))==0){
			numeroCluster=hiLowCluster(entrada);
			return numeroCluster;
		}

		i=i+32;  //Se va corriendo en el buffer por 32 bytes

	}

	return -1;}



fat_nombreLargo renameLFN(fat_nombreLargo lfn ,char * nombre){  //Cambia el nombre de una entrada de lfn

	uint16_t nombreAuxiliar[13];
	int32_t tamnombreAuxiliar = 13;

	unicode_utf8_to_utf16_inbuffer(nombre, strlen(nombre), nombreAuxiliar, &tamnombreAuxiliar);

	memcpy(lfn.nombreParte1, nombreAuxiliar, sizeof(uint16_t) * 5);
	memcpy(lfn.nombreParte2, nombreAuxiliar + 5, sizeof(uint16_t) * 6);
	memcpy(lfn.nombreParte3, nombreAuxiliar + 11, sizeof(uint16_t) * 2);


	return lfn;}




fat_entrada renameSFN(fat_entrada entrada,char *nuevoNombre){
	uint16_t i;

	if (strlen(nuevoNombre) > 4 && nuevoNombre[strlen(nuevoNombre) - 4] == '.') {
		memcpy(entrada.nombre + 8, nuevoNombre + (strlen(nuevoNombre) - 3), 3);
		for(i=0;nuevoNombre[i]!='.';i++){
			entrada.nombre[i]=nuevoNombre[i];
		}
	}

	else{
		if (strlen(nuevoNombre) <= 8 ){
			memcpy(entrada.nombre,nuevoNombre, strlen(nuevoNombre));
		} else {
			memcpy(entrada.nombre, nuevoNombre,7);
			entrada.nombre[7] = '~';
		}
	}

	return entrada;}


int32_t cambiarNombreFat32(char * path ,char *nuevoNombre){
	char *clusterLeido;
	char clusterForRecord[4096];
	int32_t numeroCluster,ultimo,pathIntermedios=0,eliminarlistaRaiz=0;
	int32_t dir,i=0,n,movimientoEnCluster=0,entradaLibre,nuevoNomEsLfn=0,nuevoNomEsSn=0;
	fat_entrada entrada,entradaSec;
	fat_nombreLargo lfn;
	char nombreLargo[13];
	char nombreCorto[13];
	int32_t index;
	clusterLeido=calloc(1,4096*sizeof(char));
	char **vector;

	if(strcmp(path,"/")==0){

		if(flagLog!=0){
			agregarEntradaLog("Error","No se ingreso un path valido");}

		return -1;
	}
	vector=string_split2(path,'/');

	for(i=1;vector[i]!=0;i++){
		pathIntermedios++;
	}
	if(pathIntermedios==1){

		dir=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
		clusterLeido=leerCluster(dir);
		eliminarlistaRaiz=1;
	}
	for(i=1;i<pathIntermedios;i++){
		if(i==1){
			numeroCluster=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
			dir=obtenerDirDelCluster(numeroCluster,bootSector);
			clusterLeido=leerCluster(dir);
			if(vector[i+2]==0){
				i++;
				break;
			}
		}
		else{
			numeroCluster=buscaNombreEnCluster(clusterLeido,vector[i]);
			dir=obtenerDirDelCluster(numeroCluster,bootSector);
			clusterLeido=leerCluster(dir);
			if(vector[i+2]==0){
				i++;
				break;
			}
		}
		//Ver si siempre los archivos tienen extencion!!! y modificar despues....
	}
	ultimo=i;
	i=0;
	entradaLibre=0;
	if (strlen(nuevoNombre) > 4 && nuevoNombre[strlen(nuevoNombre) - 4] == '.') { //me fijo si tiene extension
		if(strlen(nuevoNombre) < 13 && estaEnMayuscula(nuevoNombre)){				//si tiene extension y esta todo en mayuscula y el tamaño es de hasta 12 caracteres(aca se cuenta al punto)
			nuevoNomEsSn=1;    //va a ser un nombre corto
		}
		else{
			if(strlen(nuevoNombre)<15){
				nuevoNomEsLfn=1; // va a ser nombre largo
			}
			else{
				printf("\nel nombre %s no es valido tiene que ser de hasta 13 caracteres\n",nuevoNombre);
			}
		}
	}
	else{                             // si no tiene extension
		if(strlen(nuevoNombre)<14){
			if(estaEnMayuscula(nuevoNombre)&&strlen(nuevoNombre)<9){
				nuevoNomEsSn=1;
			}
			else{
				nuevoNomEsLfn=1;
			}
		}
		else{
			printf("\nel nombre %s no es valido tiene que ser de hasta 13 caracteres\n",nuevoNombre);
		}
	}
	for(n=0;n<128;n++){  // 16 tiene que ser variable , es cant de entradas en un cluster , osea bytes del clusterLeido /32
		memcpy(&entrada,(clusterLeido)+i,32);
		if(entrada.nombre[0]==0xe5){
			i=i+32;
			movimientoEnCluster +=32;
			continue;
		}
		if(entrada.nombre[0] == 0x00){
			movimientoEnCluster=512;
			break;
		}
		if(entrada.atributos==0x0f){                                  	// me fijo si la entrada en la que estoy es de nombre largo:
			memcpy(&lfn,&entrada,sizeof(fat_nombreLargo));   				// casteo la entrada como lfn
			memcpy(&nombreLargo,obtenerNombreLargo(lfn),13);				// obtengo el nombre largo de la entrada
			if(memcmp(vector[ultimo],nombreLargo,strlen(vector[ultimo]))==0){		// me fijo si la entrada de nombre largo es la que estoy buscando:
				if(eliminarlistaRaiz){
					eliminarEntradalistaRaiz(&listaRaiz,entrada);
				}
				if(nuevoNomEsLfn){													// me fijo si el nuevo nombre que voy a crear tiene entrada de lfn
					lfn=renameLFN(lfn,nuevoNombre);										//renombro la entrada de lfn por el nuevo nombre
					if(eliminarlistaRaiz){
						memcpy(&entradaSec,&lfn,sizeof(fat_entrada));
						agregarEntradaEnLista(&listaRaiz,entradaSec);
					}
					entradaLibre=buscarEntradasLibres(clusterLeido,2);					// buscco dos entradas libres (una para el lfn y una para fat entrada)
					memcpy(clusterLeido+entradaLibre*32,&lfn,32);						// pongo en la primer entrada encontrada la nueva entrada de nombre largo
					memcpy(&entrada,clusterLeido+i+32,32);								// busco la entrada fat de la que voy a cambiar
										if(eliminarlistaRaiz){
											eliminarEntradalistaRaiz(&listaRaiz,entrada);
										}
					entrada=renameSFN(entrada,nuevoNombre);							// obtengo una entrada fat con el nuevo nombre
										if(eliminarlistaRaiz){
											agregarEntradaEnLista(&listaRaiz,entrada);
										}
					memcpy(clusterLeido+entradaLibre*32+32,&entrada,32);				// pongo en la segunda entrada encontrada la entrada fat con el nombre cambiado
					lfn.sequencia=0xe5;
					memcpy(clusterLeido+i,&lfn,32);										// a la entrada lfn que le cambie el nombre la pongo como libre
					if(clusterLeido+i+2*32==0x00){										// si la siguiente a la entrada fat que le cambio el nombre es 0x00(todas las siguientes estan libres)
						memcpy(&entrada,clusterLeido+i+32,32);
						entrada.nombre[0]=0x00;												//entonces a esa entrada fat que le cambie el nombre la marco como 0x00(porque todas las siguientes estan libres)
						memcpy(clusterLeido+i+32,&entrada,32);
					}
					else{																// si la siguiente a la entrada fat que le cambio el nombre no es 0x00
						memcpy(&entrada,clusterLeido+i+32,32);
						entrada.nombre[0]=0xe5;												//entonces a esa entrada fat que le cambie el nombre la marco como 0xe5(entrada libre)
						memcpy(clusterLeido+i+32,&entrada,32);
					}
					break;
				}
				else{																//si el nuevo nombre no necesita entrada de lfn entonces:
					lfn.sequencia=0xe5;													// marco a la entrada de nombre largo de la que voy a cambiar como libre
					memcpy(clusterLeido+i,&lfn,32);
					memcpy(&entrada,clusterLeido+i+32,32);								//obtengo la entrada fat de la que voy a cambiar el nombre
					if(eliminarlistaRaiz){
						eliminarEntradalistaRaiz(&listaRaiz,entrada);
					}
					entrada=renameSFN(entrada,nuevoNombre);							// le cambio el nombre a la entrada fat
					if(eliminarlistaRaiz){
						agregarEntradaEnLista(&listaRaiz,entrada);
					}
					entradaLibre=buscarEntradasLibres(clusterLeido,1);				//busco una entrada libre en donde grabarla
					memcpy(clusterLeido+entradaLibre*32,&entrada,32);				//guardo la entrada fat en la entarda libre que encontre
					if(clusterLeido+i+2*32==0x00){										// si la siguiente a la entrada fat que le cambio el nombre es 0x00(todas las siguientes estan libres)
						memcpy(&entrada,clusterLeido+i+32,32);
						entrada.nombre[0]=0x00;												//entonces a esa entrada fat que le cambie el nombre la marco como 0x00(porque todas las siguientes estan libres)
						memcpy(clusterLeido+i+32,&entrada,32);
					}
					else{																// si la siguiente a la entrada fat que le cambio el nombre no es 0x00
						memcpy(&entrada,clusterLeido+i+32,32);
						entrada.nombre[0]=0xe5;												//entonces a esa entrada fat que le cambie el nombre la marco como 0xe5(entrada libre)
						memcpy(clusterLeido+i+32,&entrada,32);
					}
					break;

				}
			}
		}
		else{/*busca el nombre como entrada de nombre corto*/
			memcpy(&nombreCorto,obtenerSFNDeEntrada(entrada),13);
			if(memcmp(nombreCorto,vector[ultimo],strlen(vector[ultimo]))==0){
				if(nuevoNomEsLfn){													// me fijo si el nuevo nombre que voy a crear tiene entrada de lfn
					lfn=renameLFN(lfn,nuevoNombre);										//renombro la entrada de lfn por el nuevo nombre
					if(eliminarlistaRaiz){
						memcpy(&entradaSec,&lfn,sizeof(fat_entrada));
						agregarEntradaEnLista(&listaRaiz,entradaSec);
					}
					entradaLibre=buscarEntradasLibres(clusterLeido,2);					// busco dos entradas libres (una para el lfn y una para fat entrada)
					memcpy(clusterLeido+entradaLibre*32,&lfn,32);						// pongo en la primer entrada encontrada la nueva entrada de nombre largo
					memcpy(&entrada,clusterLeido+i,32);								// busco la entrada fat de la que voy a cambiar CAMBIO ACA!!!
					if(eliminarlistaRaiz){
						eliminarEntradalistaRaiz(&listaRaiz,entrada);
					}
					entrada=renameSFN(entrada,nuevoNombre);							// obtengo una entrada fat con el nuevo nombre
					if(eliminarlistaRaiz){
						agregarEntradaEnLista(&listaRaiz,entrada);
					}
					memcpy(clusterLeido+entradaLibre*32+32,&entrada,32);				// pongo en la segunda entrada encontrada la entrada fat con el nombre cambiado
																						// a la entrada lfn que le cambie el nombre la pongo como libre
					if(clusterLeido+i+32==0x00){										// si la siguiente a la entrada fat que le cambio el nombre es 0x00(todas las siguientes estan libres)
						memcpy(&entrada,clusterLeido+i,32);
						entrada.nombre[0]=0x00;												//entonces a esa entrada fat que le cambie el nombre la marco como 0x00(porque todas las siguientes estan libres)
						memcpy(clusterLeido+i,&entrada,32);
					}
					else{																// si la siguiente a la entrada fat que le cambio el nombre no es 0x00
						memcpy(&entrada,clusterLeido+i,32);
						entrada.nombre[0]=0xe5;												//entonces a esa entrada fat que le cambie el nombre la marco como 0xe5(entrada libre)
						memcpy(clusterLeido+i,&entrada,32);
					}
					break;
				}
				else{																//si el nuevo nombre no necesita entrada de lfn entonces:

					memcpy(&entrada,clusterLeido+i,32);								//obtengo la entrada fat de la que voy a cambiar el nombre
					if(eliminarlistaRaiz){
						eliminarEntradalistaRaiz(&listaRaiz,entrada);
					}
					entrada=renameSFN(entrada,nuevoNombre);							// le cambio el nombre a la entrada fat
					if(eliminarlistaRaiz){
						agregarEntradaEnLista(&listaRaiz,entrada);
					}
					entradaLibre=buscarEntradasLibres(clusterLeido,1);				//busco una entrada libre en donde grabarla
					memcpy(clusterLeido+entradaLibre*32,&entrada,32);				//guardo la entrada fat en la entarda libre que encontre
					if(clusterLeido+i+32==0x00){										// si la siguiente a la entrada fat que le cambio el nombre es 0x00(todas las siguientes estan libres)
						memcpy(&entrada,clusterLeido+i,32);
						entrada.nombre[0]=0x00;												//entonces a esa entrada fat que le cambie el nombre la marco como 0x00(porque todas las siguientes estan libres)
						memcpy(clusterLeido+i,&entrada,32);
					}
					else{																// si la siguiente a la entrada fat que le cambio el nombre no es 0x00
						memcpy(&entrada,clusterLeido+i,32);
						entrada.nombre[0]=0xe5;												//entonces a esa entrada fat que le cambie el nombre la marco como 0xe5(entrada libre)
						memcpy(clusterLeido+i,&entrada,32);
					}
					break;

				}
			}
		}
		i=i+32;
		movimientoEnCluster +=32;
	}
	if(movimientoEnCluster<480){
		memcpy(clusterForRecord,clusterLeido,4096);
		grabarCluster(dir,clusterForRecord);
	}
	else{

		if(flagLog!=0){
			agregarEntradaLog("Error","No se encontro la entrada con el nombre a cambiar");}

		for(index=0;vector[index] != NULL; index++){
			free(vector[index]);
		}

		free(vector);

		return -1;
	}
	for(index=0;vector[index] != NULL; index++){
			free(vector[index]);
		}

		free(vector);

	return 0;}


int32_t crearArchivoFat32(char *path){

	uint16_t NomEsSn=0;
	uint16_t NomEsLfn=0;
	char **vector;
	int32_t nroClu,nroSec,nroSectorAGrabar;
	char *clusterLeido;
	char clusterForRecord[4096];
	int32_t i,nroEntLib,numeroCluster,crearEnListaRaiz=0;
	fat_entrada nuevaEntrada,entradaSec;
	fat_nombreLargo nuevoLfn;
	int32_t index;
	char *nombre;
	char**vectorN;
	vectorN=string_split2(path,'/');
		for(i=0;vectorN[i] != 0;++i){
			if(vectorN[i+2]==0){
				++i;
				break;
			}
		}
		nombre=vectorN[i];
	if (strlen(nombre) > 4 && nombre[strlen(nombre) - 4] == '.') { //me fijo si tiene extension
			if(strlen(nombre) < 13 && estaEnMayuscula(nombre)){				//si tiene extension y esta todo en mayuscula y el tamaño es de hasta 12 caracteres(aca se cuenta al punto)
				NomEsSn=1;    //va a ser un nombre corto
			}
			else{
				if(strlen(nombre)<15){
					NomEsLfn=1; // va a ser nombre largo
				}
				else{
					if(flagLog!=0){
						agregarEntradaLog("Error","El nombre no es valido , tiene mas de 13 caracteres");}
					//printf("\nel nombre %s no es valido tiene que ser de hasta 13 caracteres sin contar el punto\n",nombre);

					return -1;
				}
			}
		}
		else{                             // si no tiene extension
			if(strlen(nombre)<14){
				if(estaEnMayuscula(nombre)&&strlen(nombre)<9){
					NomEsSn=1;
				}
				else{
					NomEsLfn=1;
				}
			}
			else{
				if(flagLog!=0){
					agregarEntradaLog("Error","El nombre no es valido, tiene mas de 13 caracteres");}
				//printf("\nel nombre %s no es valido tiene que ser de hasta 13 caracteres\n",nombre);

				return -1;
			}
		}
	vector=string_split2(path,'/');
	if(vector[2]==0){
		nroSec=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
		clusterLeido=leerCluster(nroSec);
		crearEnListaRaiz=1;
		nroSectorAGrabar=nroSec;
		numeroCluster=bootSector.cluster_raiz;
	}
	else{
		for(i=1;vector[i+1]!=0;++i){
			if(i==1){
				nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
				nroSectorAGrabar=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSectorAGrabar);
				numeroCluster=bootSector.cluster_raiz;
			}
			else{
				nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
				nroSec=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSec);
				nroSectorAGrabar=nroSec;
				numeroCluster=nroClu;

			}
		}
	}
	crearArchivoCache(path,nombre,numeroCluster,&listaCacheArchivos);

	if(NomEsLfn){
		if((nroEntLib=buscarEntradasLibres(clusterLeido,2))==-1){

			if(flagLog!=0){
				agregarEntradaLog("Error","No se encontraron entradas libres");}


			return -2; // un error distinto al del no encontrar el path en realidad deveria asignarle otro cluster para poder guardarlo.
		}
		memset(&nuevaEntrada,0,sizeof(fat_entrada));
		memset(&nuevoLfn,0,sizeof(fat_nombreLargo));
		nuevaEntrada.atributos=0x20;  //falta agregarle los demas campos
		nuevaEntrada=renameSFN(nuevaEntrada,nombre);
		nuevoLfn.atributos=0x0f;     //falta agregar los demas campos
		nuevoLfn.sequencia='A';
		nuevoLfn=renameLFN(nuevoLfn,nombre);
		memcpy(clusterLeido+nroEntLib*32,&nuevoLfn,32);
		memcpy(clusterLeido+nroEntLib*32+32,&nuevaEntrada,32);
		if(crearEnListaRaiz){
			memcpy(&entradaSec,&nuevoLfn,sizeof(fat_entrada));
			agregarEntradaEnLista(&listaRaiz,entradaSec);
			agregarEntradaEnLista(&listaRaiz,nuevaEntrada);
		}
	}
	else{
		if((nroEntLib=buscarEntradasLibres(clusterLeido,1))==-1){

			if(flagLog!=0){
				agregarEntradaLog("Error","No se encontraron entradas libres");}

		}
		memset(&nuevaEntrada,0,sizeof(fat_entrada));
		nuevaEntrada.atributos=0x20;
		nuevaEntrada=renameSFN(nuevaEntrada,nombre);
		memcpy(clusterLeido+nroEntLib*32,&nuevaEntrada,32);
		if(crearEnListaRaiz){
			agregarEntradaEnLista(&listaRaiz,nuevaEntrada);
		}
	}
	memcpy(clusterForRecord,clusterLeido,4096);
	grabarCluster(nroSectorAGrabar,clusterForRecord);
	for(index=0;vector[index] != NULL; index++){
		free(vector[index]);
	}
	free(vector);

	return 0;
	free(vectorN[0]);
	for(i=1;vectorN[i] != 0;++i){
		free(vectorN[i]);
	}
	free(vectorN);

	return 0;
}

int32_t  eliminarDirectorioFat32(const char *path){

	int32_t cantidadElementos,sizeArchivo,esArchivo,dir,eliminarEnListaRaiz,nroSectorAGrabar,nroClu,i,ret,banderaLFN,index;
	char **vector;
	char *clusterLeido;
	char clusterForRecord[4096];
	fat_entrada entradaSFN,entradaLFN;
	if((cantidadElementos=pathValido(path,listaRaiz,&sizeArchivo,&esArchivo)) == -1){

		return -1;
	}
	if(cantidadElementos != 0){

		if(flagLog!=0){
			agregarEntradaLog("Error","No esta vacio el directorio , no se puede borrar");}


		return -1;
	}
	vector=string_split2(path,'/');
	if(vector[2]==0){
		dir=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
		clusterLeido=leerCluster(dir);
		eliminarEnListaRaiz=1;
		nroSectorAGrabar=dir;
		i=1;
	}
	else{
		for(i=1;vector[i+1]!=0;++i){
			if(i==1){
				nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
				nroSectorAGrabar=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSectorAGrabar);
				if(vector[i+2]==0){
					i++;
					break;
				}
			}
			else{
				nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
				dir=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(dir);
				nroSectorAGrabar=dir;
				if(vector[i+2]==0){
					i++;
					break;
				}
			}
		}
	}
	ret=buscaNombreDevuelveEntrada(clusterLeido,vector[i],&entradaSFN,&entradaLFN,&banderaLFN);
	if(banderaLFN == 0){
		if(eliminarEnListaRaiz){
					eliminarEntradalistaRaiz(&listaRaiz,entradaSFN);
				}
		entradaSFN.nombre[0]=0xe5;
		memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
		memcpy(clusterForRecord,clusterLeido,4096);
		grabarCluster(nroSectorAGrabar,clusterForRecord);

	}
	else{
		if(eliminarEnListaRaiz){
			eliminarEntradalistaRaiz(&listaRaiz,entradaLFN);
			eliminarEntradalistaRaiz(&listaRaiz,entradaSFN);
		}
		entradaLFN.nombre[0]=0xe5;
		memcpy(clusterLeido+(ret-1)*32,&entradaLFN,sizeof(fat_entrada));
		entradaSFN.nombre[0]=0xe5;
		memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
		memcpy(clusterForRecord,clusterLeido,4096);
		grabarCluster(nroSectorAGrabar,clusterForRecord);
	}


	free(vector[0]);
	for(index=1;vector[index] != NULL; ++index){
		free(vector[index]);
	}
	free(vector);

		return 0;

}

int32_t crearDirectorioFat32(char  *path){

	uint16_t NomEsSn=0;
	uint16_t NomEsLfn=0;
	char **vector;
	char *nuevoCluster;
	char clusterForRecord[4096];
	char clusterRaiz[4096];
	int32_t nroClu,nroSec,crearEnListaRaiz=0,clusterPadre,clusterDondeEstoy,nroSecNuevaEntrada,nroSectorAGrabar;
	char *clusterLeido;
	int32_t i,nroEntLib,index;
	fat_entrada nuevaEntrada,entradaSec,primerEntrada,segundaEntrada;
	fat_nombreLargo nuevoLfn;
	char *nombre;
	char **vectorN;
	vectorN=string_split2(path,'/');
	for(i=0;vectorN[i] != 0;++i){
		if(vectorN[i+2]==0){
			++i;
			break;
		}
	}
	nombre=vectorN[i];

	if (strlen(nombre) > 4 && nombre[strlen(nombre) - 4] == '.') { //me fijo si tiene extension
		if(strlen(nombre) < 13 && estaEnMayuscula(nombre)){				//si tiene extension y esta todo en mayuscula y el tamaño es de hasta 12 caracteres(aca se cuenta al punto)
			NomEsSn=1;    //va a ser un nombre corto
		}
		else{
			if(strlen(nombre)<15){
				NomEsLfn=1; // va a ser nombre largo
			}
			else{

				if(flagLog!=0){
					agregarEntradaLog("Error","No es valido el nombre ingresado ,tiene mas de 13 caracteres");}


				return -1;
			}
		}
	}
	else{                             // si no tiene extension
		if(strlen(nombre)<14){
			if(estaEnMayuscula(nombre)&&strlen(nombre)<9){
				NomEsSn=1;
			}
			else{
				NomEsLfn=1;
			}
		}
		else{

			if(flagLog!=0){
								agregarEntradaLog("Error","No es valido el nombre ingresado ,tiene mas de 13 caracteres");}



			return -1;
		}
	}
	vector=string_split2(path,'/');
	if(vector[2]==0){
		nroSec=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
		clusterLeido=leerCluster(nroSec);
		//magia para que no modifique el clusterLeido
		memcpy(clusterRaiz,clusterLeido,4096);
		crearEnListaRaiz=1;
		clusterPadre=bootSector.cluster_raiz;
		nroSectorAGrabar=nroSec;
	}
	else{
		for(i=1;vector[i+1]!=0;++i){
			if(i==1){
				nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
				nroSectorAGrabar=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSectorAGrabar);
			}
			else{
				nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
				nroSec=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSec);
				nroSectorAGrabar=nroSec;
			}
		}
		clusterPadre=nroClu;
	}
	clusterDondeEstoy=obtenerClusterLibre(bootSector);  //MODIFICA EL CLUSTER RAIZ POR ALGUNA RAZON!
	nuevoCluster=(char*)calloc(1,sizeof(char)*4096);
	nroSecNuevaEntrada=obtenerDirDelCluster(clusterDondeEstoy,bootSector);
	memset(&primerEntrada,0,sizeof(fat_entrada));
	memset(&segundaEntrada,0,sizeof(fat_entrada));
	primerEntrada=renameSFN(primerEntrada,".");
	segundaEntrada=renameSFN(segundaEntrada,"..");
	llenarLaEntradaconHiLow(&primerEntrada,clusterDondeEstoy);
	llenarLaEntradaconHiLow(&segundaEntrada,clusterPadre);
	memcpy(nuevoCluster,&primerEntrada,sizeof(fat_entrada));
	memcpy(nuevoCluster+32,&segundaEntrada,sizeof(fat_entrada));
	memcpy(clusterForRecord,nuevoCluster,4096);
	grabarCluster(nroSecNuevaEntrada,clusterForRecord);
	if(NomEsLfn){
		if((nroEntLib=buscarEntradasLibres(clusterRaiz,2))==-1){

			if(flagLog!=0){
				agregarEntradaLog("Error","No se encontraron entradas libres");}

			//buscar el siguiente cluster o asignarle alguno
		}
		memset(&nuevaEntrada,0,sizeof(fat_entrada));
		memset(&nuevoLfn,0,sizeof(fat_nombreLargo));
		nuevaEntrada.atributos=0x10;  //falta agregarle los demas campos
		llenarLaEntradaconHiLow(&nuevaEntrada,clusterDondeEstoy);
		nuevaEntrada=renameSFN(nuevaEntrada,nombre);
		nuevoLfn.atributos=0x0f;     //falta agregar los demas campos
		nuevoLfn.sequencia='A';
		nuevoLfn=renameLFN(nuevoLfn,nombre);
		memcpy(clusterRaiz+nroEntLib*32,&nuevoLfn,32);
		memcpy(clusterRaiz+nroEntLib*32+32,&nuevaEntrada,32);
		if(crearEnListaRaiz){
			memcpy(&entradaSec,&nuevoLfn,sizeof(fat_entrada));
			agregarEntradaEnLista(&listaRaiz,entradaSec);
			agregarEntradaEnLista(&listaRaiz,nuevaEntrada);
		}
	}
	else{
		if((nroEntLib=buscarEntradasLibres(clusterRaiz,1))==-1){

			//buscar el siguiente cluster o asignarle alguno
		}
		memset(&nuevaEntrada,0,sizeof(fat_entrada));
		nuevaEntrada.atributos=0x10;  //falta agregarle los demas campos
		llenarLaEntradaconHiLow(&nuevaEntrada,clusterDondeEstoy);
		nuevaEntrada=renameSFN(nuevaEntrada,nombre);
		memcpy(clusterRaiz+nroEntLib*32,&nuevaEntrada,32);
		if(crearEnListaRaiz){
			agregarEntradaEnLista(&listaRaiz,nuevaEntrada);
		}
	}
	memcpy(clusterForRecord,clusterRaiz,4096);
	grabarCluster(nroSectorAGrabar,clusterForRecord);
	for(index=0;vector[index] != NULL; index++){
		free(vector[index]);
	}

	free(vector);

	return 0;
	free(vectorN[0]);
	for(i=1;vectorN[i] != 0;++i){
		free(vectorN[i]);
	}
	free(vectorN);

return 0;}



int32_t estaEnMayuscula(char nombre[]){
	int32_t i,mayuscula=0;
	for(i=0;i<strlen(nombre);++i){
		if(isupper(nombre[i])||nombre[i]=='.'){
			mayuscula++;
		}

	}
	if(mayuscula==strlen(nombre)){
		return mayuscula;
	}
	return 0;
}


int32_t esEntradaNombreValida(char nombreEntrada[]){
	int32_t i,valida=1;
	for(i=0;i<8;++i){
		if(nombreEntrada[i]=='~'){
			valida=0;
			break;
		}
		if(nombreEntrada[i]=='.'){
			continue;
		}
	}
	return valida;
}


void mostrarListadoFat32(const char *path,ptrListaNom_t *listaNom,ptrLista listaRaiz){
	int32_t i;
	fat_nombreLargo lfn;
	fat_entrada entrada;
	char nombreLargo[14];
	char nombreCorto[12];
	char extension[4];
	int32_t nroClu,nroSec;
	char *clusterLeido;
	char **vector;
	vector=calloc(1,strlen(path)+1);
	int32_t index;

	if(strcmp(path,"/")==0){
		nroSec=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
		clusterLeido=leerCluster(nroSec);
	}
	else{
		vector=string_split2(path,'/');  //Cambie la declaracion aca por que sino tira error abajo , esto estaba asi char **vector=... , vector lo declare arriba
		for(i=1;vector[i]!=0;++i){
			if(i==1){
				nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);  //USAR LISTARAIZ!!!!!!
				nroSec=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSec);
			}
			else{
				nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
				nroSec=obtenerDirDelCluster(nroClu,bootSector);
				clusterLeido=leerCluster(nroSec);
			}
		}
	}
	for(i=0;i<128;i++){
		memcpy(&entrada,clusterLeido+i*32,sizeof(fat_entrada));
		if(entrada.nombre[0]==0xe5){
			continue;
		}
		if(entrada.nombre[0] == 0x00){
			break;
		}
		if(entrada.atributos==0x0f){
			memcpy(&lfn,clusterLeido+i*32,sizeof(fat_nombreLargo));
			memcpy(&nombreLargo,obtenerNombreLargo(lfn),13);
			if(lfn.sequencia!=0xe5 && memcmp(nombreLargo,".Trash",6) != 0){/*verificar que no sea una entrada corrompida y tuve que saca el directorio trash*/
				/*fijarme si tiene extension si es archivo*/

				agregarEnListaNombres(&(*listaNom),nombreLargo);
			}
			i++;
		}
		else{
			if(esEntradaNombreValida(entrada.nombre)){
				memset(nombreCorto,0,12);
				memcpy(nombreCorto,entrada.nombre,8);
				if(entrada.nombre[9]!=0x0){/*fijarme si tiene extencion si es archivo*/
					memset(extension,0,4);
					memcpy(extension,".",1);
					memcpy(extension+1,entrada.nombre+8,3);
					memcpy(nombreCorto+tamCadena(nombreCorto),extension,4);
				}
				if(memcmp(nombreCorto,".",1)==0 || memcmp(nombreCorto,"..",2)==0){
					continue;
				}
//
				agregarEnListaNombres(&(*listaNom),nombreCorto);
			}

		}
	}

	for(index=0;vector[index] != NULL; index++){
		free(vector[index]);
	}
	free(vector);
	return;
}

/*devuelve -1 si no encontro las entradas que necesitamos sino devuelve la primer entrada de las que necesitamos numerado de 0 a 127*/

int32_t buscarEntradasLibres(char *cluster,int32_t cantidadEntradas){
	int32_t nroEntrada=0,i,primeraEntradaEncontrada=-1;
	int32_t encontro=0,encontrados=cantidadEntradas;
	fat_nombreLargo lfn;
	for(i=0;i<128;i++){
		memcpy(&lfn,cluster+i*32,32);
		while(0xe5==lfn.sequencia || 0x00==lfn.sequencia){
			if(encontrados==cantidadEntradas){
				primeraEntradaEncontrada=i;
			}
			encontrados--;
			if(encontrados==0){
				nroEntrada=i;
				encontro=1;
				break;
			}
			i++;
			memcpy(&lfn,cluster+i*32,32);
		}
		if(encontro){
			break;
		}
		else{
			encontrados=cantidadEntradas;
		}
	}
	if(i==128){
		return -1;
	}

	return primeraEntradaEncontrada;
}




char* leerCluster(int32_t primerSector){
		paqueteNIPC *paqueteP;
		paqueteNIPC paquete;
		int32_t n,m;
		payloadEscritura_t payloadEscritura;
		clusterRec_t cluster[8];
		char returna[4096];
		char bufferLog[200];



		paqueteP=malloc(sizeof(paqueteNIPC));

		/* Creo el Socket: SOCK_STREAM para TCP y SOCK_DGRAM par UDP */
		 int descriptor = socket(AF_INET, SOCK_STREAM, 0);

		/* Direccion Local */
		struct sockaddr_in *local_address = malloc(sizeof(struct sockaddr_in));
		/* Direccion remota ( a la que me quiero conectar )*/
		struct sockaddr_in *remote_address = malloc(sizeof(struct sockaddr_in));
		/* Direccion remota ( a la que me quiero conectar )*/
		struct sockaddr_in *remote_addressPDD = malloc(sizeof(struct sockaddr_in));

		{       /* Con esto fuerzo a que el puerto local sea el 5201 y que tome la IP por defecto de la PC */
			local_address->sin_family = AF_INET;
			local_address->sin_addr.s_addr = INADDR_ANY;
			local_address->sin_port = htons(PuertoPFS);

			bind(descriptor, (struct sockaddr *)local_address, sizeof(struct sockaddr_in));
		}

		{       /* Con esto indico que me quiero conectar al puerto 9034 de la IP 127.0.0.1 (localhost)-->RAID */
			remote_address->sin_family = AF_INET;
			remote_address->sin_addr.s_addr = inet_addr(direccionIPRaid);
			remote_address->sin_port = htons(PuertoDelRaid);
		}

		{       /* Con esto indico que me quiero conectar al puerto 9048 de la IP 127.0.0.1 (localhost) -> PDD*/
			remote_addressPDD->sin_family = AF_INET;
			remote_addressPDD->sin_addr.s_addr = inet_addr(direccionIPPDD);
			remote_addressPDD->sin_port = htons(PuertoPDD);
		}

		reconnect:

				/* Me conecto al servidor */
				if(flagRAID==0){
				if(connect(descriptor, (struct sockaddr *)remote_address , sizeof(struct sockaddr_in))==-1){
					//perror("connect");
					puts("No se pudo conectar al RAID");
					flagRAID = 1;
				};
				};

				if(flagRAID==1){
				if(connect(descriptor, (struct sockaddr *)remote_addressPDD, sizeof(struct sockaddr_in))==-1){
							perror("connect");
							puts("No se pudo conectar al PDD");
						};
				}

		paqueteP->num_msg = 0;
		paqueteP->longitud = 0;
		memcpy(&paqueteP->payload,&cantConex,sizeof(int32_t));

		if(send(descriptor, paqueteP, sizeof(paqueteNIPC), 0)==-1){
			perror("send");
			puts("Falló el envío del paquete para HS");
		};

		if(recv(descriptor, &paquete, sizeof(paqueteNIPC), MSG_WAITALL)==-1){
			perror("recv");
			puts("No se pudo recibir la respuesta del intento de Handshake");
		};

		if((paquete.num_msg==0)&&(paquete.longitud==0)){
			//puts("Handshake exitoso");


	//---------------------------------------- Aca va el main del pfs--------------------------------------


			for(n=0;n<8;n++){
				paqueteP->num_msg = 1;
				paqueteP->longitud = sizeof(int32_t);
				memcpy(&paqueteP->payload,&primerSector,sizeof(int32_t));

				if(send(descriptor,paqueteP,sizeof(paqueteNIPC),0)==-1){
					perror("send");
				};
				cluster[n].numSector = primerSector;
				primerSector++;
			};

			for(n=0;n<8;n++){

				if(recv(descriptor,&paquete,sizeof(paqueteNIPC),MSG_WAITALL)==-1){
							perror("recv");
				};

				if(paquete.num_msg == 2){

				memcpy(&payloadEscritura, paquete.payload, sizeof(payloadEscritura));

				m = 0;

				while(cluster[m].numSector!=payloadEscritura.sector){
					m++;
				};

				memcpy(cluster[m].contenido,payloadEscritura.contenido,sizeof(payloadEscritura.contenido));

				};

			};

			for(n=0;n<8;n++){
				memcpy(returna+(512*n),cluster[n].contenido,512);
			};


	//-------------------------------------------------------------------------------------------------------


		} else {
			if(paquete.num_msg==-1){
				printf("%s\n",paquete.payload);
				puts("Handshake falló");
			};


			if(paquete.num_msg==-2){
									//printf("%s\n",paquete.payload);
									goto reconnect;
								};
		};


		/* Cierro el socket y por ende la conexion */
		free(paqueteP);
		close(descriptor);

		free(local_address);
		free(remote_address);
		free(remote_addressPDD);
	//	usleep(100000);
		return returna;
	}

void grabarCluster(int32_t primerSector, char *contCluster){
		paqueteNIPC *paqueteP;
		paqueteNIPC paquete;
		int32_t n;
		payloadEscritura_t payloadEscritura;
		clusterRec_t cluster[8];

		paqueteP=malloc(sizeof(paqueteNIPC));

		/* Creo el Socket: SOCK_STREAM para TCP y SOCK_DGRAM par UDP */
		 int descriptor = socket(AF_INET, SOCK_STREAM, 0);

		/* Direccion Local */
		struct sockaddr_in *local_address = malloc(sizeof(struct sockaddr_in));
		/* Direccion remota ( a la que me quiero conectar )*/
		struct sockaddr_in *remote_address = malloc(sizeof(struct sockaddr_in));
		/* Direccion remota ( a la que me quiero conectar )*/
		struct sockaddr_in *remote_addressPDD = malloc(sizeof(struct sockaddr_in));

		{       /* Con esto fuerzo a que el puerto local sea el 5201 y que tome la IP por defecto de la PC */
			local_address->sin_family = AF_INET;
			local_address->sin_addr.s_addr = INADDR_ANY;
			local_address->sin_port = htons(PuertoPFS);

			bind(descriptor, (struct sockaddr *)local_address, sizeof(struct sockaddr_in));
		}

		{       /* Con esto indico que me quiero conectar al puerto 9034 de la IP 127.0.0.1 (localhost)-->RAID */
			remote_address->sin_family = AF_INET;
			remote_address->sin_addr.s_addr = inet_addr(direccionIPRaid);
			remote_address->sin_port = htons(PuertoDelRaid);
		}

		{       /* Con esto indico que me quiero conectar al puerto 9048 de la IP 127.0.0.1 (localhost) -> PDD*/
			remote_addressPDD->sin_family = AF_INET;
			remote_addressPDD->sin_addr.s_addr = inet_addr(direccionIPPDD);
			remote_addressPDD->sin_port = htons(PuertoPDD);
		}

		/* Me conecto al servidor */
		reconnect:

			/* Me conecto al servidor */
			if(flagRAID==0){
			if(connect(descriptor, (struct sockaddr *)remote_address , sizeof(struct sockaddr_in))==-1){
				//perror("connect");
				puts("No se pudo conectar al RAID");
				flagRAID = 1;
			};
			};

			if(flagRAID==1){
			if(connect(descriptor, (struct sockaddr *)remote_addressPDD, sizeof(struct sockaddr_in))==-1){
						perror("connect");
						puts("No se pudo conectar al PDD");
					};
			};

		paqueteP->num_msg = 0;
		paqueteP->longitud = 0;
		memcpy(&paqueteP->payload,&cantConex,sizeof(int32_t));

		if(send(descriptor, paqueteP, sizeof(paqueteNIPC), 0)==-1){
			perror("send");
			puts("Falló el envío del paquete para HS");
		};

		if(recv(descriptor, &paquete, sizeof(paqueteNIPC), MSG_WAITALL)==-1){
			perror("recv");
			puts("No se pudo recibir la respuesta del intento de Handshake");
		};

		if((paquete.num_msg==0)&&(paquete.longitud==0)){
			//puts("Handshake exitoso");




			for(n=0;n<8;n++){
						paqueteP->num_msg = 3;
						paqueteP->longitud = sizeof(uint32_t) + sizeof(payloadEscritura.contenido);

						payloadEscritura.sector = primerSector;
						memcpy(payloadEscritura.contenido,contCluster+(512*n),512);

						memcpy(&paqueteP->payload,&payloadEscritura,sizeof(payloadEscritura));

						if(send(descriptor,paqueteP,sizeof(paqueteNIPC),0)==-1){
							perror("send");
						};
						cluster[n].numSector = primerSector;
						primerSector++;
					};



		} else {
			if(paquete.num_msg==-1){
				printf("%s\n",paquete.payload);
				puts("Handshake falló");
			};

			if(paquete.num_msg==-2){
				//printf("%s\n",paquete.payload);
				goto reconnect;
			};

		};


				/* Cierro el socket y por ende la conexion */
				free(paqueteP);
				close(descriptor);

				free(local_address);
				free(remote_address);
				free(remote_addressPDD);
			//	usleep(100000);
			}






int32_t buscaNombreDevuelveEntradaListaRaiz(ptrLista lista,char * nombre,fat_entrada *entradaSFN,fat_entrada *entradaLFN){

	fat_nombreLargo lfn;
	char nombreLargo[13];
	char nombreCorto[13];
	char bufferLog[100];
	ptrLista ptr;

	ptr=lista;
	while(ptr!=NULL){
		if(ptr->entradaRaiz.atributos==0x0f){
			memcpy(&lfn,&(ptr->entradaRaiz),sizeof(fat_nombreLargo));
			memcpy(nombreLargo,obtenerNombreLargo(lfn),13);
			if(memcmp(nombre,nombreLargo,strlen(nombreLargo))==0){
				memcpy(&(*entradaLFN),&(ptr->entradaRaiz),32);
				ptr=ptr->siguiente;
				memcpy(&(*entradaSFN),&(ptr->entradaRaiz),32);
				return 0;
			}
		}
		else {
			memcpy(&nombreCorto,obtenerSFNDeEntrada(ptr->entradaRaiz),13);
			if(memcmp(nombre,nombreCorto,strlen(nombreCorto))==0){
				memcpy(&(*entradaSFN),&(ptr->entradaRaiz),32);
				return 0;
			}

		}
		ptr=ptr->siguiente;
	}

	if(flagLog!=0){
		sprintf(bufferLog,"No se encontro la entrada con el nombre %s",nombre);
		agregarEntradaLog("Error",bufferLog);}


	return -1;
}



int32_t buscaNombreDevuelveEntrada(char * cluster , char * nombre, fat_entrada *entadaSFN,fat_nombreLargo *entradaLFN,int32_t *banderaNoLFN){


		int32_t n,i=0;
		char nombreLargo[15];
		char nombreCorto[13];
		fat_entrada entrada;
		fat_nombreLargo lfn;


		for(n=0;n<128;n++){  //128 cluster


			memcpy(&entrada,cluster+i,32);

			if(entrada.atributos==0x0f){
				memcpy(&lfn,&entrada,sizeof(fat_nombreLargo));
				memcpy(&nombreLargo,obtenerNombreLargo(lfn),13);
				if(memcmp(nombre,nombreLargo,strlen(nombreLargo))==0){
					//me corro a la proxima entrada y la casteo por q seguro es de entrada fat ya que no hay mas de una entrada de lfn..
					memcpy(&(*entradaLFN),cluster+i,32);
					(*banderaNoLFN)=1;
					memcpy(&(*entadaSFN),cluster+i+32,32);
					n++;
					return n;

				}

			}
			memcpy(&nombreCorto,obtenerSFNDeEntrada(entrada),13);
			if(memcmp(nombre,nombreCorto,strlen(nombre))==0){   //HAY QUE OBTENER EL NOMBRE CORTO DE LA ENTRADA!!
				memcpy(&(*entadaSFN),&entrada,32);
				(*banderaNoLFN)=0;
				return n;
			}



			i=i+32;  //Se va corriendo en el buffer por 32 bytes


		}

return -1 ;
}



//int32_t cambiarTamanio(fat_BootSector bootSector,char * path,int32_t nuevoTamanio,ptrLista listaRaiz,int32_t *tablaFat,int32_t *primerClusSiEsCero){
//
//
//	char ** vector;
//	int32_t i,n=2,j=1,nroSec,nroClu,primClu=0,cantidad=0,index,ret,banderaLFN,dir,retorno,libre;
//	char clusterLeido1[4096];
//	char *clusterRaiz;
//	char *clusterLeido;
//	char clusterRaiz1[4096];
//	char clusterForRecord[4096];
//	int32_t tamCluster=bootSector.bytes_por_sector*bootSector.sectores_por_cluster;
//	int32_t clustersNuevoTamanio=0;
//	int32_t clustersActualTamanio=0;
//	char bufferLog[100];
//	fat_entrada entradaLFN,entradaSFN;
//
//	vector=calloc(1,strlen(path)+1);
//	vector=string_split2(path,'/');
//
//	for(i=1;vector[i]!=0;++i){
//
//		n++;
////-------------------------------------------------------PARA TRUNCAR UN ARCHIVO DE LA LISTA RAIZ--------------------------------------------------------
//		if(i==1 && vector[n-1]==0){
//
//			retorno=buscaEntradaCambiaTamanioListRaiz(vector[i],nuevoTamanio);//Actualiza la entrada de la lista raiz con el nuevo tamaño
//
//
//			if(retorno==-1){
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//				return -1;}
//
//
//			dir=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
//			clusterRaiz=leerCluster(dir);
//			memcpy(clusterRaiz1,clusterRaiz,4096);
//
//			ret=buscaNombreDevuelveEntrada(clusterRaiz,vector[i],&entradaSFN,&entradaLFN,&banderaLFN);
//
//			if(ret==-1){
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//
//				if(flagLog!=0){
//					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
//					agregarEntradaLog("Error",bufferLog);}
//				return -1;
//			}
//
//
//			clustersNuevoTamanio= ceil( (double)nuevoTamanio / (double)tamCluster );
//			clustersActualTamanio= ceil( (double)entradaSFN.tamanioDelArchivo / (double)tamCluster );
//
//
//
//
//			if( clustersNuevoTamanio == clustersActualTamanio ){
//
//				return 1;}
//
//			if( clustersNuevoTamanio > clustersActualTamanio ){
//
//				//Agregar Clusters
//				primClu=hiLowCluster(entradaSFN);
//				cantidad=(clustersNuevoTamanio-clustersActualTamanio);
//
//
//
//				if(primClu==0){
//					pthread_mutex_lock(&mutexFat);
//					libre=obtenerClusterLibre(bootSector); //ACA PISA LA VARIABLE
//					(*primerClusSiEsCero)=libre;
// 					cantidad--;
//					llenarLaEntradaconHiLow(&entradaSFN,libre);
//					buscaEntradaCambiaPrimerClusterListRaiz(vector[i],libre);
//					memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
//					memcpy(clusterForRecord,clusterRaiz1,4096);
//					grabarCluster(dir,clusterForRecord);
//
//
//					if(cantidad==0){
//						llenarLaEntradaconHiLow(&entradaSFN,libre);
//						entradaSFN.tamanioDelArchivo=nuevoTamanio;
//
//						//Actualizar tamaño en la cache????
//
//
//						memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
//						memcpy(clusterForRecord,clusterRaiz1,4096);
//						grabarCluster(dir,clusterForRecord);
//
//
//						buscaEntradaCambiaPrimerClusterListRaiz(vector[i],libre);
//
//
//						pthread_mutex_unlock(&mutexFat);
//						return 0;
//					}
//					pthread_mutex_unlock(&mutexFat);
//					agregarClusters(tablaFat,cantidad,bootSector,libre);
//					entradaSFN.tamanioDelArchivo=nuevoTamanio;
//								memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
//								memcpy(clusterForRecord,clusterRaiz1,4096);
//								grabarCluster(dir,clusterForRecord);
//
//
//								return 1;
//
//				}
//
//
//				agregarClusters(tablaFat,cantidad,bootSector,primClu);
//
//
//			}
//			else {
//
//				primClu=hiLowCluster(entradaSFN);
//				//Remuevo clusters
//				cantidad=(clustersActualTamanio-clustersNuevoTamanio);
//
//				removerClusters(tablaFat,primClu,cantidad);
//
//				if(clustersNuevoTamanio==0){//COMO REMUEVO TODOS LOS CLUSTERS , SETEO CLUS HI Y LOW CON 0
//
//									llenarLaEntradaconHiLow(&entradaSFN,0);
//									buscaEntradaCambiaPrimerClusterListRaiz(vector[i],0);
//									memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
//									memcpy(clusterForRecord,clusterRaiz1,4096);
//									grabarCluster(dir,clusterForRecord);
//								}
//
//			}
//
//			entradaSFN.tamanioDelArchivo=nuevoTamanio;
//			memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
//			memcpy(clusterForRecord,clusterRaiz1,4096);
//			grabarCluster(dir,clusterForRecord);
//
//
//			return 1;
//		}
//
////------------------------------------------------------ACA!!!!!!!------------------------------------------------------------------------------------
//
//		if(i==1){
//
//			nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
//			if(nroClu==-1){
//				if(flagLog!=0){
//					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
//					agregarEntradaLog("Error",bufferLog);}
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//				return -1;}
//			nroSec=obtenerDirDelCluster(nroClu,bootSector);
//			clusterLeido=leerCluster(nroSec);
//			memcpy(clusterLeido1,clusterLeido,4096);
//		}
//		if(vector[n]==0){
//			j++;
//
//			ret=buscaNombreDevuelveEntrada(clusterLeido,vector[j],&entradaSFN,&entradaLFN,&banderaLFN);
//			if(ret==-1){
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//				if(flagLog!=0){
//					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[j]);
//					agregarEntradaLog("Error",bufferLog);}
//				return -1;}
//			break;
//		}
//		else{
//			nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
//			if(nroClu==-1){
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//				if(flagLog!=0){
//					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
//					agregarEntradaLog("Error",bufferLog);}
//				return -1;
//			}
//			nroSec=obtenerDirDelCluster(nroClu,bootSector);
//			clusterLeido=leerCluster(nroSec);
//		}
//
//	}
//
//
//
//	clustersNuevoTamanio= ceil( (double)nuevoTamanio / (double)tamCluster );
//	clustersActualTamanio= ceil( (double)entradaSFN.tamanioDelArchivo / (double)tamCluster );
//
//
//
//
//	if( clustersNuevoTamanio == clustersActualTamanio ){
//		for(index=0;vector[index] != NULL; index++){
//			free(vector[index]);}
//		free(vector);
//		return 1;
//	}
//
//	if( clustersNuevoTamanio > clustersActualTamanio ){
//
//		//Agregar Clusters
//		primClu=hiLowCluster(entradaSFN);
//		cantidad=(clustersNuevoTamanio-clustersActualTamanio);
//
//		if(primClu==0){//Caso de archivo recien creado con primClus=0
//			pthread_mutex_lock(&mutexFat);
//			primClu=obtenerClusterLibre(bootSector);
//			(*primerClusSiEsCero)=primClu;
//			cantidad--;
//			if(cantidad==0){
//				llenarLaEntradaconHiLow(&entradaSFN,primClu);
//
//
//				//MODIFICAR TAMAÑO DE LA ENTRADA ???
//
//				entradaSFN.tamanioDelArchivo=nuevoTamanio;
//				memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
//				memcpy(clusterForRecord,clusterLeido,4096);
//				grabarCluster(nroSec,clusterForRecord);
//
//				for(index=0;vector[index] != NULL; index++){
//					free(vector[index]);}
//				free(vector);
//
//				pthread_mutex_unlock(&mutexFat);
//				return 0;
//			}
//			//Acualizar entrada con primClu!!!!!
//			llenarLaEntradaconHiLow(&entradaSFN,primClu);
//
//			pthread_mutex_unlock(&mutexFat); //Desbloqueo si cantidad no es igual a 0!!
//		}
//
//		agregarClusters(tablaFat,cantidad,bootSector,primClu);
//	}
//
//	else {
//		//Remuevo clusters
//		primClu=hiLowCluster(entradaSFN);
//		cantidad=(clustersActualTamanio-clustersNuevoTamanio);
//		removerClusters(tablaFat,primClu,cantidad);
//
//		if(clustersNuevoTamanio==0){
//							//COMO REMUEVO TODOS LOS CLUSTERS , SETEO CLUS HI Y LOW CON 0
//							llenarLaEntradaconHiLow(&entradaSFN,0);
//							memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
//							memcpy(clusterForRecord,clusterLeido,4096);
//							grabarCluster(nroSec,clusterForRecord);
//						}
//	}
//
//	//Actualizar el nuevo tamaño a la entrada
//	entradaSFN.tamanioDelArchivo=nuevoTamanio;
//	memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
//	memcpy(clusterForRecord,clusterLeido,4096);
//	grabarCluster(nroSec,clusterForRecord);
//
//	for(index=0;vector[index] != NULL; index++){
//		free(vector[index]);}
//	free(vector);
//
//	return 1;}




//---------------------------PRUEBA CAMBIAR TAMAÑO-----------------------------------------

int32_t cambiarTamanio(fat_BootSector bootSector,char * path,int32_t nuevoTamanio,ptrLista listaRaiz,int32_t *tablaFat,int32_t *primerClusSiEsCero){


	char ** vector;
	int32_t i,n=2,j=1,nroSec,nroClu,primClu=0,cantidad=0,index,ret,banderaLFN,dir,retorno;
	char clusterLeido1[4096];
	char *clusterRaiz;
	char *clusterLeido;
	char clusterRaiz1[4096];
	char clusterForRecord[4096];
	int32_t tamCluster=bootSector.bytes_por_sector*bootSector.sectores_por_cluster;
	int32_t clustersNuevoTamanio=0;
	int32_t clustersActualTamanio=0;
	char bufferLog[100];
	fat_entrada entradaLFN,entradaSFN;

	vector=calloc(1,strlen(path)+1);
	vector=string_split2(path,'/');

	for(i=1;vector[i]!=0;++i){

		n++;
//-------------------------------------------------------PARA TRUNCAR UN ARCHIVO DE LA LISTA RAIZ--------------------------------------------------------
		if(i==1 && vector[n-1]==0){

			retorno=buscaEntradaCambiaTamanioListRaiz(vector[i],nuevoTamanio);//Actualiza la entrada de la lista raiz con el nuevo tamaño


			if(retorno==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				return -1;}


			dir=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
			clusterRaiz=leerCluster(dir);
			memcpy(clusterRaiz1,clusterRaiz,4096);

			ret=buscaNombreDevuelveEntrada(clusterRaiz,vector[i],&entradaSFN,&entradaLFN,&banderaLFN);

			if(ret==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);

				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
				return -1;
			}


			clustersNuevoTamanio= ceil( (double)nuevoTamanio / (double)tamCluster );
			clustersActualTamanio= ceil( (double)entradaSFN.tamanioDelArchivo / (double)tamCluster );




			if( clustersNuevoTamanio == clustersActualTamanio ){

				return 1;}

			if( clustersNuevoTamanio > clustersActualTamanio ){

				//Agregar Clusters
				primClu=hiLowCluster(entradaSFN);
				cantidad=(clustersNuevoTamanio-clustersActualTamanio);



				if(primClu==0){
					pthread_mutex_lock(&mutexFat);
					primClu=obtenerClusterLibre(bootSector); //ACA PISA LA VARIABLE
					(*primerClusSiEsCero)=primClu;
 					cantidad--;
					llenarLaEntradaconHiLow(&entradaSFN,primClu);
					buscaEntradaCambiaPrimerClusterListRaiz(vector[i],primClu);
					memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
					memcpy(clusterForRecord,clusterRaiz1,4096);
					grabarCluster(dir,clusterForRecord);


					if(cantidad==0){
						llenarLaEntradaconHiLow(&entradaSFN,primClu);
						entradaSFN.tamanioDelArchivo=nuevoTamanio;

						//Actualizar tamaño en la cache????


						memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
						memcpy(clusterForRecord,clusterRaiz1,4096);
						grabarCluster(dir,clusterForRecord);


						buscaEntradaCambiaPrimerClusterListRaiz(vector[i],primClu);


						pthread_mutex_unlock(&mutexFat);
						return 0;
					}

					pthread_mutex_unlock(&mutexFat);
				}


				agregarClusters(tablaFat,cantidad,bootSector,primClu);


			}
			else {

				primClu=hiLowCluster(entradaSFN);
				//Remuevo clusters
				cantidad=(clustersActualTamanio-clustersNuevoTamanio);

				removerClusters(tablaFat,primClu,cantidad);

				if(clustersNuevoTamanio==0){//COMO REMUEVO TODOS LOS CLUSTERS , SETEO CLUS HI Y LOW CON 0

									llenarLaEntradaconHiLow(&entradaSFN,0);
									buscaEntradaCambiaPrimerClusterListRaiz(vector[i],0);
									memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
									memcpy(clusterForRecord,clusterRaiz1,4096);
									grabarCluster(dir,clusterForRecord);
								}

			}

			entradaSFN.tamanioDelArchivo=nuevoTamanio;
			memcpy(clusterRaiz1+ret*32,&entradaSFN,sizeof(fat_entrada));
			memcpy(clusterForRecord,clusterRaiz1,4096);
			grabarCluster(dir,clusterForRecord);


			return 1;
		}

//------------------------------------------------------ACA!!!!!!!------------------------------------------------------------------------------------

		if(i==1){

			nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
			if(nroClu==-1){
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				return -1;}
			nroSec=obtenerDirDelCluster(nroClu,bootSector);
			clusterLeido=leerCluster(nroSec);
			memcpy(clusterLeido1,clusterLeido,4096);
		}
		if(vector[n]==0){
			j++;

			ret=buscaNombreDevuelveEntrada(clusterLeido,vector[j],&entradaSFN,&entradaLFN,&banderaLFN);
			if(ret==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[j]);
					agregarEntradaLog("Error",bufferLog);}
				return -1;}
			break;
		}
		else{
			nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
			if(nroClu==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
				return -1;
			}
			nroSec=obtenerDirDelCluster(nroClu,bootSector);
			clusterLeido=leerCluster(nroSec);
		}

	}



	clustersNuevoTamanio= ceil( (double)nuevoTamanio / (double)tamCluster );
	clustersActualTamanio= ceil( (double)entradaSFN.tamanioDelArchivo / (double)tamCluster );




	if( clustersNuevoTamanio == clustersActualTamanio ){
		for(index=0;vector[index] != NULL; index++){
			free(vector[index]);}
		free(vector);
		return 1;
	}

	if( clustersNuevoTamanio > clustersActualTamanio ){

		//Agregar Clusters
		primClu=hiLowCluster(entradaSFN);
		cantidad=(clustersNuevoTamanio-clustersActualTamanio);

		if(primClu==0){//Caso de archivo recien creado con primClus=0
			pthread_mutex_lock(&mutexFat);
			primClu=obtenerClusterLibre(bootSector);
			(*primerClusSiEsCero)=primClu;
			cantidad--;
			if(cantidad==0){
				llenarLaEntradaconHiLow(&entradaSFN,primClu);


				//MODIFICAR TAMAÑO DE LA ENTRADA ???

				entradaSFN.tamanioDelArchivo=nuevoTamanio;
				memcpy(clusterLeido1+ret*32,&entradaSFN,sizeof(fat_entrada)); //USARR clusterLeido1
				memcpy(clusterForRecord,clusterLeido1,4096);
				grabarCluster(nroSec,clusterForRecord);

				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);

				pthread_mutex_unlock(&mutexFat);
				return 0;
			}
			//Acualizar entrada con primClu!!!!!
			llenarLaEntradaconHiLow(&entradaSFN,primClu);

			pthread_mutex_unlock(&mutexFat); //Desbloqueo si cantidad no es igual a 0!!
		}

		agregarClusters(tablaFat,cantidad,bootSector,primClu);
	}

	else {
		//Remuevo clusters
		primClu=hiLowCluster(entradaSFN);
		cantidad=(clustersActualTamanio-clustersNuevoTamanio);
		removerClusters(tablaFat,primClu,cantidad);

		if(clustersNuevoTamanio==0){
							//COMO REMUEVO TODOS LOS CLUSTERS , SETEO CLUS HI Y LOW CON 0
							llenarLaEntradaconHiLow(&entradaSFN,0);
							memcpy(clusterLeido1+ret*32,&entradaSFN,sizeof(fat_entrada));
							memcpy(clusterForRecord,clusterLeido1,4096);
							grabarCluster(nroSec,clusterForRecord);
						}
	}

	//Actualizar el nuevo tamaño a la entrada
	entradaSFN.tamanioDelArchivo=nuevoTamanio;
	memcpy(clusterLeido1+ret*32,&entradaSFN,sizeof(fat_entrada));
	memcpy(clusterForRecord,clusterLeido1,4096);
	grabarCluster(nroSec,clusterForRecord);

	for(index=0;vector[index] != NULL; index++){
		free(vector[index]);}
	free(vector);

	return 1;}


//-----------------------------------------------------------------------------------------






int32_t pathValido(char *path,ptrLista listaRaiz,int32_t *sizeArchivo,int32_t *esArchivo){ //Si existe el path devuelve 1 si es arch cant si es dir (cant es la cantidad de arch de un dir)

	// VER SI ESTA EN CACHE

	char ** vector;
	int32_t i,n=2,j=1,nroSec,nroClu,index,ret,cantidadElemDir=0,banderaLFN;
	char *clusterLeido;
	char bufferLog[100];
	fat_entrada entradaSFN;
	fat_nombreLargo entradaLFN;
	ptrListaNom_t lista=NULL,ptr=NULL;
//	vector=calloc(1,strlen(path)+1);
	vector=string_split2(path,'/');
	for(i=1;vector[i]!=0;++i){
		n++;
		if(vector[2]==NULL){  								//SI SOLAMENTE ES DIR DE LISTA RAIZ
			if((ret=buscaNombreDevuelveEntradaListaRaiz(listaRaiz,vector[1],&entradaSFN,&entradaLFN)) ==-1){
				if(flagLog!=0){
									sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[1]);
									agregarEntradaLog("Error",bufferLog);}
				return -1;
			}
			if(entradaSFN.atributos==0x20){//archivo
				(*esArchivo)=1;
				(*sizeArchivo)=entradaSFN.tamanioDelArchivo;
				return 1;}
			if(entradaSFN.atributos==0x10){//Directorio
				(*esArchivo)=0;
				//Ver la cantidad de arch que tiene y devolverlo!
				mostrarListadoFat32(path,&lista,listaRaiz);
				ptr=lista;
				while(ptr!=NULL){
					cantidadElemDir++;
					ptr=ptr->siguiente;
				}
			return cantidadElemDir;}//hay que retornar cant!
		}


	if(i==1){

		nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
		if(nroClu==-1){
			if(flagLog!=0){
				sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
				agregarEntradaLog("Error",bufferLog);}
			return -1;}
		nroSec=obtenerDirDelCluster(nroClu,bootSector);
		clusterLeido=leerCluster(nroSec);
	}
	if(vector[n]==0){
		j++;

		ret=buscaNombreDevuelveEntrada(clusterLeido,vector[j],&entradaSFN,&entradaLFN,&banderaLFN);
		if(ret==-1){
			if(flagLog!=0){
				sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[j]);
				agregarEntradaLog("Error",bufferLog);}
		return -1;}
		if(entradaSFN.atributos==0x20){//archivo
			(*esArchivo)=1;
			(*sizeArchivo)=entradaSFN.tamanioDelArchivo;
			return 1;}
		if(entradaSFN.atributos==0x10){//Directorio
			(*esArchivo)=0;
			//Ver la cantidad de arch que tiene y devolverlo!
			mostrarListadoFat32(path,&lista,listaRaiz);
			ptr=lista;
			while(ptr!=NULL){
				cantidadElemDir++;
				ptr=ptr->siguiente;
			}
			return cantidadElemDir;}//hay que retornar cant!
	}
	else{
		nroClu=buscaNombreEnCluster(clusterLeido,vector[i+1]);
		nroSec=obtenerDirDelCluster(nroClu,bootSector);
		clusterLeido=leerCluster(nroSec);
		j++;
	}

}

for(index=0;vector[index] != NULL; index++){
	free(vector[index]);}
free(vector);

return 0;}




int32_t removerArchivo(char *path,int32_t *tablaFat){
	char ** vector;
	int32_t i,n=2,j=1,nroSec,nroClu,index,ret,banderaLFN,primClu,cantClusArch,direc;
	char *clusterLeido;
	fat_entrada entradaSFN,entradaLFN;
	char bufferLog[100];
	char clusterForRecord[4096];

	vector=calloc(1,strlen(path)+1);
	vector=string_split2(path,'/');

	for(i=1;vector[i]!=0;++i){

		if(i==1 && vector[n]==0){ //Es un archivo del Directorio raiz    //Borrar la entrada de la lista raiz , la SFN y LFN

			direc=obtenerDirDelCluster(bootSector.cluster_raiz,bootSector);
			clusterLeido=leerCluster(direc);
			ret=buscaNombreDevuelveEntrada(clusterLeido,vector[i],&entradaSFN,&entradaLFN,&banderaLFN);
			if(ret==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
				return -1;}


			mostrarListaN(listaRaiz);

			eliminarEntradalistaRaiz(&listaRaiz,entradaSFN);

			mostrarListaN(listaRaiz);


			primClu=hiLowCluster(entradaSFN);

			if(banderaLFN!=0){
				eliminarEntradalistaRaiz(&listaRaiz,entradaLFN);
				entradaLFN.nombre[0]=0xe5;
				memcpy(clusterLeido+(ret-1)*32,&entradaLFN,sizeof(fat_entrada));
			}

			entradaSFN.nombre[0]=0xe5;
			memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
			memcpy(clusterForRecord,clusterLeido,4069);
			grabarCluster(direc,clusterForRecord);


			cantClusArch=clustersDeUnArchivo(tablaFat,primClu);

			if(cantClusArch==0){
				for(index=0;vector[index] != NULL; index++){
								free(vector[index]);}
							free(vector);

						return 0;
			}

			removerClusters(tablaFat,primClu,cantClusArch);


			//Ver tablaFAT si la esta persistiendo bien..

			for(index=0;vector[index] != NULL; index++){
				free(vector[index]);}
			free(vector);

		return 0;}
//--------------------------------------------------------------------------------------------------------------------------------------------
		n++;

		if(i==1){

			nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
			if(nroClu==-1){
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
			for(index=0;vector[index] != NULL; index++){
				free(vector[index]);}
			free(vector);
			return -1;}
			nroSec=obtenerDirDelCluster(nroClu,bootSector);
			clusterLeido=leerCluster(nroSec);
		}
		if(vector[n]==0){
			j++;

			ret=buscaNombreDevuelveEntrada(clusterLeido,vector[j],&entradaSFN,&entradaLFN,&banderaLFN);
			if(ret==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[j]);
					agregarEntradaLog("Error",bufferLog);}
				//printf("Error , no se encontro el nombre en el cluster\n");
				return -1;}
			break;
		}
		else{
			nroClu=buscaNombreEnCluster(clusterLeido,vector[i]);
			if(nroClu==-1){
				for(index=0;vector[index] != NULL; index++){
					free(vector[index]);}
				free(vector);
				if(flagLog!=0){
					sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
					agregarEntradaLog("Error",bufferLog);}
				//printf("Erorr,no se encontro el nombre en el cluster");
				return -1;}
			nroSec=obtenerDirDelCluster(nroClu,bootSector);
			clusterLeido=leerCluster(nroSec);
		}

	}

	primClu=hiLowCluster(entradaSFN);
	if(banderaLFN!=0){
		entradaLFN.nombre[0]=0xe5;
		memcpy(clusterLeido+(ret-1)*32,&entradaLFN,sizeof(fat_entrada));
	}
	entradaSFN.nombre[0]=0xe5;
	memcpy(clusterLeido+ret*32,&entradaSFN,sizeof(fat_entrada));
	memcpy(clusterForRecord,clusterLeido,4096);
	grabarCluster(nroSec,clusterForRecord);


	cantClusArch=clustersDeUnArchivo(tablaFat,primClu);

	if(cantClusArch==0){

		for(index=0;vector[index] != NULL; index++){
			free(vector[index]);}
		free(vector);

		return 0;
	}

	removerClusters(tablaFat,primClu,cantClusArch);




	for(index=0;vector[index] != NULL; index++){
		free(vector[index]);}
	free(vector);

	return 0;}






int32_t pathValidoCluster(char *path,ptrLista listaRaiz,int32_t *sizeArchivo,int32_t *primerClusterArch,int32_t *clusterEntrada){

	// VER SI ESTA EN CACHE


	char ** vector;
	int32_t i,n=2,j=1,nroSec,nroClu,index,ret,cantidadElemDir=0,banderaLFN;
	char *clusterLeido;
	char bufferLog[100];
	fat_entrada entradaSFN;
	fat_nombreLargo entradaLFN;
	ptrListaNom_t lista=NULL,ptr=NULL;
//	vector=calloc(1,strlen(path)+1);
	vector=string_split2(path,'/');
	for(i=1;vector[i]!=0;++i){

		n++;
		if(vector[2]==NULL){  								//SI SOLAMENTE ES DIR DE LISTA RAIZ

			if((ret=buscaNombreDevuelveEntradaListaRaiz(listaRaiz,vector[1],&entradaSFN,&entradaLFN)) ==-1){
				return -1;
			}
			if(entradaSFN.atributos==0x20){//archivo
				(*primerClusterArch)=hiLowCluster(entradaSFN);
				(*sizeArchivo)=entradaSFN.tamanioDelArchivo;
				(*clusterEntrada)=bootSector.cluster_raiz;
				return 1;}
			if(entradaSFN.atributos==0x10){//Directorio
				//Ver la cantidad de arch que tiene y devolverlo!
				mostrarListadoFat32(path,&lista,listaRaiz);
				ptr=lista;
				while(ptr!=NULL){
					cantidadElemDir++;
					ptr=ptr->siguiente;
				}
				(*clusterEntrada)=bootSector.cluster_raiz;
			return cantidadElemDir;}//hay que retornar cant!
		}


	if(i==1){
		nroClu=buscaNombreDevuelveClusterEnListaRaiz(listaRaiz,vector[i]);
		if(nroClu==-1){
			if(flagLog!=0){
						sprintf(bufferLog,"No se encontro la entrada con el nombre %s en la listaRaiz",vector[i]);
						agregarEntradaLog("Error",bufferLog);}

			return -1;}
		nroSec=obtenerDirDelCluster(nroClu,bootSector);
		clusterLeido=leerCluster(nroSec);
		(*clusterEntrada)=nroClu;
	}
	if(vector[n]==0){
		j++;
		ret=buscaNombreDevuelveEntrada(clusterLeido,vector[j],&entradaSFN,&entradaLFN,&banderaLFN);
		if(ret==-1){
			if(flagLog!=0){

				agregarEntradaLog("Error","no se encontro el archivo en la lista cache");}

		return -1;}
		if(entradaSFN.atributos==0x20){//archivo
			(*primerClusterArch)=hiLowCluster(entradaSFN);
			(*sizeArchivo)=entradaSFN.tamanioDelArchivo;
			return 1;}
		if(entradaSFN.atributos==0x10){//Directorio
			//Ver la cantidad de arch que tiene y devolverlo!
			mostrarListadoFat32(path,&lista,listaRaiz);
			ptr=lista;
			while(ptr!=NULL){
				cantidadElemDir++;
				ptr=ptr->siguiente;
			}
			return cantidadElemDir;}//hay que retornar cant!
	}
	else{
		nroClu=buscaNombreEnCluster(clusterLeido,vector[i+1]);
		nroSec=obtenerDirDelCluster(nroClu,bootSector);
		clusterLeido=leerCluster(nroSec);
		(*clusterEntrada)=nroClu;
		j++;
	}
}
for(index=0;vector[index] != NULL; index++){
	free(vector[index]);}
free(vector);

return 0;}


size_t leerArchivo(char * path ,ptrLista listaRaiz,fat_BootSector bootSector,int32_t *tablaFat,char* buff,off_t desde,size_t cantidadALeer){

	//buscar en la cache
	int16_t encontroArchivoEnCache=0,encontroBloqueEnCache=0,cacheVacia=0;
	ptrCacheArchivo cacheArchivo;
	ptrBloque bloqueArchivo;
	int32_t i;
	char **vectorN;
	char *nombreArchivo;
	int32_t direcCluster;
	//si no  lo encuentra devuelve NULL
	vectorN=string_split2(path,'/');
	for(i=0;vectorN[i] != 0;++i){
		if(vectorN[i+2]==0){
			++i;
			break;
		}
	}
	nombreArchivo=vectorN[i];
	cacheArchivo=buscarArchivoEnCache(path,listaCacheArchivos);
	encontroArchivoEnCache=1;
	if(cacheArchivo == NULL){
		if(flagLog!=0){

				agregarEntradaLog("Error","no se encontro el archivo en la lista cachE");}

		encontroArchivoEnCache=0;
	}
	char *cluster;
	int32_t n,j,nroClusterEntrada;
	int32_t tamanioCluster=4096;
	int32_t  primerClusterDelArchivo,numeroDeClusterALeer,proximoClusterALeer,offsetEnCluster;
	int tamanioCopiado = 0;
	cluster=calloc(1,4096*sizeof(char));
	int32_t sizeArchivo;


    pathValidoCluster(path,listaRaiz,&sizeArchivo,&primerClusterDelArchivo,&nroClusterEntrada);
		//calculo el cluster desde donde quiero leer
		long clusterDesde= floorl((double) desde / (double)tamanioCluster);

		if(desde>sizeArchivo){ //Quieren leer mas de lo q ocupa el arch
			return 0;
		}

		if(desde+cantidadALeer > sizeArchivo){
			cantidadALeer=sizeArchivo-desde;
		}


		n=primerClusterDelArchivo;
		//Buscar cual es el cluster a partir del cual quieren leer
		for(j=0;j<clusterDesde;j++){

			numeroDeClusterALeer=n;
			n=tablaFat[n];
		}//creo q funca!

		if(clusterDesde==0){
			numeroDeClusterALeer=primerClusterDelArchivo;
		}
		if(!encontroArchivoEnCache){
			crearArchivoCache(path,nombreArchivo,nroClusterEntrada,&listaCacheArchivos);
			cacheArchivo=buscarArchivoEnCache(path,listaCacheArchivos);
			encontroArchivoEnCache=1;
		}
		if(cacheArchivo->bloquesSubLista == NULL){
			cacheVacia=1;
		}
		if(!cacheVacia){
			bloqueArchivo=buscaClusterDeArchivoCache(cacheArchivo,numeroDeClusterALeer);
			encontroBloqueEnCache=0;
			if(bloqueArchivo != NULL){
				memcpy(cluster,&bloqueArchivo->bloqueInfo,4096);
				encontroBloqueEnCache=1;
			}
			if(!encontroBloqueEnCache){
				direcCluster=obtenerDirDelCluster(numeroDeClusterALeer,bootSector);
				cluster=leerCluster(direcCluster);
				agregarInfoAbloqueCache(&cacheArchivo,numeroDeClusterALeer,sizeArchivo,cluster);
			}
		}
		else{
			direcCluster=obtenerDirDelCluster(numeroDeClusterALeer,bootSector);
			cluster=leerCluster(direcCluster);
		}

		int tamanioACopiar = tamanioCluster - (desde - clusterDesde * tamanioCluster);
		offsetEnCluster=(desde - clusterDesde * tamanioCluster);

			if (tamanioACopiar > cantidadALeer) {
			tamanioACopiar = cantidadALeer;
		}

		do {

			memcpy(buff+tamanioCopiado,cluster+offsetEnCluster,tamanioACopiar);

			tamanioCopiado = tamanioCopiado + tamanioACopiar;
			if (tamanioCopiado < cantidadALeer){
				//tengo que seguir leyendo , busco el proximo cluster.


				proximoClusterALeer=tablaFat[numeroDeClusterALeer];
				numeroDeClusterALeer=proximoClusterALeer; //CAMBIO NUEVO , SINO NO AVANZA SIEMPRE SE QUEDA EN EL MISMO!!!!!!!!!!!!!!




				if(!cacheVacia){
					bloqueArchivo=buscaClusterDeArchivoCache(cacheArchivo,proximoClusterALeer);
					encontroBloqueEnCache=0;
					if(bloqueArchivo != NULL){
						memcpy(cluster,&bloqueArchivo->bloqueInfo,4096);
						encontroBloqueEnCache=1;
					}
					if(!encontroBloqueEnCache){
						direcCluster=obtenerDirDelCluster(proximoClusterALeer,bootSector);
						cluster=leerCluster(direcCluster);
						agregarInfoAbloqueCache(&cacheArchivo,proximoClusterALeer,sizeArchivo,cluster);
					}
				}
				else{
					direcCluster=obtenerDirDelCluster(proximoClusterALeer,bootSector);
					cluster=leerCluster(direcCluster);
				}
				offsetEnCluster=0;
				if (tamanioCopiado + tamanioCluster <= cantidadALeer) {
					tamanioACopiar = tamanioCluster;
				}
				else {
					tamanioACopiar = cantidadALeer - tamanioCopiado;
				}
			}

		} while (tamanioCopiado < cantidadALeer);

		free(vectorN[0]);
		for(i=1;vectorN[i] != 0;++i){
			free(vectorN[i]);
		}
		free(vectorN);

return tamanioCopiado;
}


size_t escribirArchivo(char * path ,ptrLista listaRaiz,fat_BootSector bootSector,int32_t *tablaFat,char* buff,off_t desde,size_t cantidadAEscribir){

	uint16_t encontroArchivoEnCache=0,encontroBloqueEnCache=0;
	ptrCacheArchivo cacheArchivo;
	ptrBloque bloqueArchivo;
	char *cluster;
	int32_t n,j,cacheVacia=0,primerClusterSiEsCero;
	int32_t tamanioCluster=4096;
	int32_t  primerClusterDelArchivo,numeroDeClusterAEscribir,proximoClusterAEscribir,offsetEnCluster,aux;
 	int32_t tamanioCopiado = 0;
	int32_t direcCluster;
	cluster=calloc(1,4096*sizeof(char));
	int32_t sizeArchivo,nroClusterEntrada,i;
	char **vector;
	char *nombreArchivo;
	char clusterForRecord[4096];
	cacheArchivo=buscarArchivoEnCache(path,listaCacheArchivos);
	encontroArchivoEnCache=1;
	if(cacheArchivo == NULL){

		if(flagLog!=0){
			agregarEntradaLog("Error","No se encontro el archivo en la lista cache");}
		//printf("no se encontro el archivo en la lista cache");
		encontroArchivoEnCache=0;
	}
	vector=string_split2(path,'/');
	for(i=0;vector[i] != 0;++i){
		if(vector[i+2]==0){
			++i;
			break;
		}
	}
	nombreArchivo=vector[i];


    	aux=desde+1;

		//calculo el cluster desde donde quiero escribir
		long clusterDesde= floorl((double) aux / (double)tamanioCluster);

		pathValidoCluster(path,listaRaiz,&sizeArchivo,&primerClusterDelArchivo,&nroClusterEntrada);

		if(desde+cantidadAEscribir > sizeArchivo){
			cambiarTamanio(bootSector,path,desde+cantidadAEscribir,listaRaiz,tablaFat,&primerClusterSiEsCero);
		}




		n=primerClusterDelArchivo;

		if(primerClusterDelArchivo==0){
			primerClusterDelArchivo=primerClusterSiEsCero;
		}

		//Buscar cual es el cluster a partir del cual quieren leer
		for(j=0;j<clusterDesde;j++){
			n=tablaFat[n];
			numeroDeClusterAEscribir=n;
		}//Testear bien esto!!

		if(clusterDesde==0){
			numeroDeClusterAEscribir=primerClusterDelArchivo;
		}

		if(!encontroArchivoEnCache){
			crearArchivoCache(path,nombreArchivo,nroClusterEntrada,&listaCacheArchivos);
			cacheArchivo=buscarArchivoEnCache(path,listaCacheArchivos);
			encontroArchivoEnCache=1;
		}
		if(cacheArchivo->bloquesSubLista == NULL){
			cacheVacia=1;
		}
		if(!cacheVacia){
			bloqueArchivo=buscaClusterDeArchivoCache(cacheArchivo,numeroDeClusterAEscribir);
			encontroBloqueEnCache=0;
			if(bloqueArchivo != NULL){
				memcpy(cluster,&bloqueArchivo->bloqueInfo,4096);
				encontroBloqueEnCache=1;
			}
			if(!encontroBloqueEnCache){
				direcCluster=obtenerDirDelCluster(numeroDeClusterAEscribir,bootSector);
				cluster=leerCluster(direcCluster);
				agregarInfoAbloqueCache(&cacheArchivo,numeroDeClusterAEscribir,desde+cantidadAEscribir,cluster);
			}
		}
		else{
			direcCluster=obtenerDirDelCluster(numeroDeClusterAEscribir,bootSector);
			cluster=leerCluster(direcCluster);
		}
		int tamanioACopiar = tamanioCluster - (desde - clusterDesde * tamanioCluster);
	    offsetEnCluster=(desde - clusterDesde * tamanioCluster);

			if (tamanioACopiar > cantidadAEscribir) {
			tamanioACopiar = cantidadAEscribir;
		}
		do {
			memcpy(cluster+offsetEnCluster,buff,tamanioACopiar);
			if(!cacheVacia){
				bloqueArchivo=buscaClusterDeArchivoCache(cacheArchivo,numeroDeClusterAEscribir);
				if(bloqueArchivo != NULL){
					buscaClusterDeArchivoCacheYCambiaInfo(&cacheArchivo,numeroDeClusterAEscribir,cluster,desde+cantidadAEscribir);
					encontroBloqueEnCache=1;
				}
			}
			else{
				memcpy(clusterForRecord,cluster,4096);
				grabarCluster(direcCluster,clusterForRecord);
			}
			tamanioCopiado = tamanioCopiado + tamanioACopiar;
			if (tamanioCopiado < cantidadAEscribir){
				//tengo que seguir leyendo , busco el proximo cluster.
				proximoClusterAEscribir=tablaFat[numeroDeClusterAEscribir];
				numeroDeClusterAEscribir=proximoClusterAEscribir;
				if(!cacheVacia){
					bloqueArchivo=buscaClusterDeArchivoCache(cacheArchivo,numeroDeClusterAEscribir);
					encontroBloqueEnCache=0;
					if(bloqueArchivo != NULL){
						memcpy(cluster,&bloqueArchivo->bloqueInfo,4096);
						encontroBloqueEnCache=1;
					}
					if(!encontroBloqueEnCache){
						direcCluster=obtenerDirDelCluster(numeroDeClusterAEscribir,bootSector);
						cluster=leerCluster(direcCluster);
						agregarInfoAbloqueCache(&cacheArchivo,numeroDeClusterAEscribir,desde+cantidadAEscribir,cluster);
					}
				}
				else{
					direcCluster=obtenerDirDelCluster(numeroDeClusterAEscribir,bootSector);
					cluster=leerCluster(direcCluster);
				}
				offsetEnCluster=0;
				if (tamanioCopiado + tamanioCluster <= cantidadAEscribir) {
					tamanioACopiar = tamanioCluster;
				}
				else {
					tamanioACopiar = cantidadAEscribir - tamanioCopiado;
				}
			}
		} while (tamanioCopiado < cantidadAEscribir);
		free(vector[0]);
		for(i=1;vector[i] != 0;++i){
			free(vector[i]);
		}
		free(vector);

return tamanioCopiado;
}

char *obtenerSFNDeEntrada(fat_entrada entrada){

	char nombre[13];
	char extension[5];
	int32_t i=0;
	memset(nombre,'\0',13);
	memset(extension,'\0',5);

	while(entrada.nombre[i]!=0x0){

		if(entrada.nombre[i]==0x20){//SI Tiene un /0 la entrada esta mal, siempre deberia tener este valor para estar bien!
			break;
		}

	memcpy(nombre+i,&entrada.nombre[i],1);
	i++;
	}
	if(entrada.nombre[10]!=0x0){  //0x20 es '' osea vacio
		memcpy(extension,".",strlen("."));
		memcpy(extension+1,&entrada.nombre[8],1);
		memcpy(extension+2,&entrada.nombre[9],1);
		memcpy(extension+3,&entrada.nombre[10],1);

		memcpy(nombre+strlen(nombre),extension,strlen(extension));
	}

return nombre;}


int32_t buscaEntradaCambiaTamanioListRaiz(char * nombre,int32_t nuevoTamanio){
	fat_nombreLargo lfn;
	char nombreLargo[13];
	char nombreCorto[13];
	char bufferLog[100];
	ptrLista ptr;

	ptr=listaRaiz;
	while(ptr!=NULL){
		if(ptr->entradaRaiz.atributos==0x0f){
			memcpy(&lfn,&(ptr->entradaRaiz),sizeof(fat_nombreLargo));
			memcpy(nombreLargo,obtenerNombreLargo(lfn),13);
			if(memcmp(nombre,nombreLargo,strlen(nombre))==0){
				ptr=ptr->siguiente;
				ptr->entradaRaiz.tamanioDelArchivo=nuevoTamanio;
				return 0;
			}
		}
		else {
			memcpy(&nombreCorto,obtenerSFNDeEntrada(ptr->entradaRaiz),13);
			if(memcmp(nombre,nombreCorto,strlen(nombreCorto))==0){
				ptr->entradaRaiz.tamanioDelArchivo=nuevoTamanio;
				return 0;
			}

		}
		ptr=ptr->siguiente;
	}
	if(flagLog!=0){
			sprintf(bufferLog,"No se encontro la entrada con el nombre %s",nombre);
			agregarEntradaLog("Error",bufferLog);}
	//printf("No se encontro la entrada con el nombre:%s\n",nombre);
	return -1;
}

int32_t buscaEntradaCambiaPrimerClusterListRaiz(char * nombre,int32_t primerClusterArch){
	fat_nombreLargo lfn;
	char nombreLargo[13];
	char nombreCorto[13];
	char bufferLog[100];
	ptrLista ptr;

	ptr=listaRaiz;
	while(ptr!=NULL){
		if(ptr->entradaRaiz.atributos==0x0f){
			memcpy(&lfn,&(ptr->entradaRaiz),sizeof(fat_nombreLargo));
			memcpy(nombreLargo,obtenerNombreLargo(lfn),13);
			if(memcmp(nombre,nombreLargo,strlen(nombre))==0){
				ptr=ptr->siguiente;
				llenarLaEntradaconHiLow(&(ptr->entradaRaiz),primerClusterArch);
				return 0;
			}
		}
		else {
			memcpy(&nombreCorto,obtenerSFNDeEntrada(ptr->entradaRaiz),13);
			if(memcmp(nombre,nombreCorto,strlen(nombreCorto))==0){
				llenarLaEntradaconHiLow(&(ptr->entradaRaiz),primerClusterArch);
				return 0;
			}

		}
		ptr=ptr->siguiente;
	}
	if(flagLog!=0){
			sprintf(bufferLog,"No se encontro la entrada con el nombre %s",nombre);
			agregarEntradaLog("Error",bufferLog);}
	return -1;
}



//------------------------------IMPRESION DE LA CACHE-----------------------------------------------

int32_t agregarEntradaArchivoCache(char *Data)
{
	struct timeval valorTiempo;
	struct timezone zonaTiempo;
	struct tm *tiempoMaquina=NULL;
	time_t rawtime;
	struct tm *horaDelSistema=NULL;
	char BufferCache[500];

	memset(BufferCache,'\0',sizeof(BufferCache));
	time(&rawtime);
	horaDelSistema=localtime(&rawtime);
	gettimeofday(&valorTiempo, &zonaTiempo);
	tiempoMaquina=localtime(&valorTiempo.tv_sec);

	sprintf(BufferCache,"%02d:%02d:%02d.%03d  %s \r\n\r\n",horaDelSistema->tm_hour,horaDelSistema->tm_min,horaDelSistema->tm_sec,((valorTiempo.tv_usec)/1000),Data);
	escribirArchivoCache(BufferCache, "cache_dump.txt");

return 0;
}

int32_t escribirArchivoCache(char *BufferCache, char *nombreArchivo)
{
		FILE *manejadorArchivo;
		manejadorArchivo = fopen (nombreArchivo, "a+" );

		fputs(BufferCache,manejadorArchivo);

		fclose (manejadorArchivo );

return 0;
}





void imprimirCache(){
	ptrCacheArchivo ptr=NULL;
	ptrBloque ptrBloque=NULL;
	int32_t i;
	ptr=listaCacheArchivos;
	char BufferCache[200];
	char BufferCacheInfo[4096];

		while(ptr!=NULL){

			sprintf(BufferCache,"Archivo:%s\n",ptr->path); //NOMBRE DEL ARCHIVO
			agregarEntradaArchivoCache(BufferCache);

			sprintf(BufferCache,"Tamaño del bloque De Cache:%d Kb\n",tamCache); //TAMAÑO DEL BLOQUE DE LA CACHE
			agregarEntradaArchivoCache(BufferCache);

			sprintf(BufferCache,"Cantidad de bloques De Cache:%d \n",ptr->cantBloques); //CANTIDAD DE BLOQUES
			agregarEntradaArchivoCache(BufferCache);

			ptrBloque=ptr->bloquesSubLista;

		for(i=0;i<ptr->cantBloques;i++){
			sprintf(BufferCacheInfo,"Contenido de bloque De Cache %d:%s\n",i,ptrBloque->bloqueInfo);//INFO DE LOS BLOQUES
			agregarEntradaArchivoCache(BufferCacheInfo);
			ptrBloque=ptrBloque->ptrSigBloque;
		}
	ptr=ptr->ptrSigArchivo;	}
}

//--------------------------FIN DE IMPRESION DE LA CACHE------------------------------------------------
